Class TeardownAttribute
Namespace: Belay.Attributes
Assembly: Belay.Attributes.dll
Marks a method to be executed during device disconnection or disposal. Methods decorated with this attribute are automatically called when the device connection is terminated, providing cleanup and resource management capabilities.
[AttributeUsage(AttributeTargets.Method)]
public sealed class TeardownAttribute : Attribute
Inheritance
object ← Attribute ← TeardownAttribute
Inherited Members
Attribute.Equals(object?), Attribute.GetCustomAttribute(Assembly, Type), Attribute.GetCustomAttribute(Assembly, Type, bool), Attribute.GetCustomAttribute(MemberInfo, Type), Attribute.GetCustomAttribute(MemberInfo, Type, bool), Attribute.GetCustomAttribute(Module, Type), Attribute.GetCustomAttribute(Module, Type, bool), Attribute.GetCustomAttribute(ParameterInfo, Type), Attribute.GetCustomAttribute(ParameterInfo, Type, bool), Attribute.GetCustomAttributes(Assembly), Attribute.GetCustomAttributes(Assembly, bool), Attribute.GetCustomAttributes(Assembly, Type), Attribute.GetCustomAttributes(Assembly, Type, bool), Attribute.GetCustomAttributes(MemberInfo), Attribute.GetCustomAttributes(MemberInfo, bool), Attribute.GetCustomAttributes(MemberInfo, Type), Attribute.GetCustomAttributes(MemberInfo, Type, bool), Attribute.GetCustomAttributes(Module), Attribute.GetCustomAttributes(Module, bool), Attribute.GetCustomAttributes(Module, Type), Attribute.GetCustomAttributes(Module, Type, bool), Attribute.GetCustomAttributes(ParameterInfo), Attribute.GetCustomAttributes(ParameterInfo, bool), Attribute.GetCustomAttributes(ParameterInfo, Type), Attribute.GetCustomAttributes(ParameterInfo, Type, bool), Attribute.GetHashCode(), Attribute.IsDefaultAttribute(), Attribute.IsDefined(Assembly, Type), Attribute.IsDefined(Assembly, Type, bool), Attribute.IsDefined(MemberInfo, Type), Attribute.IsDefined(MemberInfo, Type, bool), Attribute.IsDefined(Module, Type), Attribute.IsDefined(Module, Type, bool), Attribute.IsDefined(ParameterInfo, Type), Attribute.IsDefined(ParameterInfo, Type, bool), Attribute.Match(object?), Attribute.TypeId, object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()
Examples
Hardware Resource Cleanup
public class MotorController : Device
{
[Setup]
private async Task InitializeMotorsAsync()
{
await ExecuteAsync(@"
import machine
motor_left = machine.PWM(machine.Pin(12))
motor_right = machine.PWM(machine.Pin(13))
motor_left.freq(1000)
motor_right.freq(1000)
");
}
[Teardown]
private async Task StopMotorsAsync()
{
await ExecuteAsync(@"
# Safely stop motors before disconnect
try:
if 'motor_left' in globals():
motor_left.duty_u16(0)
motor_left.deinit()
if 'motor_right' in globals():
motor_right.duty_u16(0)
motor_right.deinit()
print('Motors stopped safely')
except Exception as e:
print(f'Motor cleanup error: {e}')
");
}
}
State Persistence
public class DataLogger : Device
{
[Teardown]
private async Task SaveDataAsync()
{
await ExecuteAsync(@"
import json
try:
# Save any pending data before disconnect
if 'pending_data' in globals() and pending_data:
with open('data_backup.json', 'w') as f:
json.dump(pending_data, f)
print(f'Saved {len(pending_data)} pending records')
# Update status file
status = {
'last_disconnect': time.time(),
'clean_shutdown': True
}
with open('status.json', 'w') as f:
json.dump(status, f)
except Exception as e:
print(f'Data save error: {e}')
");
}
}
Multi-Stage Teardown
public class ComplexDevice : Device
{
[Teardown(Order = 1)] // Execute first
private async Task StopBackgroundTasksAsync()
{
await ExecuteAsync(@"
# Stop background threads
monitoring_active = False
data_collection_active = False
# Wait briefly for threads to notice
import time
time.sleep_ms(100)
");
}
[Teardown(Order = 2)] // Execute second
private async Task SaveStateAsync()
{
await ExecuteAsync(@"
# Save current state
save_device_state()
flush_data_buffers()
");
}
[Teardown(Order = 3)] // Execute last
private async Task CleanupHardwareAsync()
{
await ExecuteAsync(@"
# Final hardware cleanup
disable_all_outputs()
release_hardware_resources()
");
}
}
Error-Resilient Teardown
public class RobustDevice : Device
{
[Teardown(IgnoreErrors = true)]
private async Task BestEffortCleanupAsync()
{
await ExecuteAsync(@"
# Clean up everything we can, ignore individual failures
cleanup_tasks = [
lambda: cleanup_sensors(),
lambda: stop_background_threads(),
lambda: save_critical_data(),
lambda: disable_hardware()
]
for task in cleanup_tasks:
try:
task()
except Exception as e:
print(f'Cleanup task failed: {e}')
print('Best-effort cleanup completed')
");
}
}
Remarks
The ensures proper cleanup when device connections end, whether due to explicit disconnection, network issues, or application shutdown. This is essential for releasing hardware resources, saving state, and graceful shutdown of background operations.
Teardown methods are executed in reverse declaration order within a class, with derived class teardown methods running before base class teardown methods. This ensures proper cleanup hierarchy and dependency management.
Teardown execution characteristics:
- Always executes, even if setup or other operations failed
- Has limited time to complete before forcible disconnection
- Should be robust against partial initialization states
- Failures are logged but do not prevent disconnection
Constructors
Initializes a new instance of the class.
Properties
Gets or sets a value indicating whether gets or sets whether this teardown method is critical and must execute even in emergency disconnection scenarios.
Gets or sets a value indicating whether gets or sets whether errors in this teardown method should be ignored. When true, exceptions from this method will be logged but will not prevent other teardown methods from executing or the disconnection from proceeding.
Gets or sets the order in which this teardown method should be executed relative to other teardown methods in the same class.
Gets or sets the timeout for teardown method execution in milliseconds. Teardown operations have limited time to complete before forcible disconnection.
Methods
Returns a string that represents the current .