未验证 提交 e90adbb5 编写于 作者: T Thomas Ibel 提交者: GitHub

LibGpiodDriver handle TaskCanceledException in Dispose (#1825)

上级 e38856a0
......@@ -54,5 +54,22 @@ namespace System.Device.Gpio.Tests
controller.ClosePin(InputPin);
}
}
[Fact]
public void UnregisterPinValueChangedShallNotThrow()
{
using var gc = new GpioController(GetTestNumberingScheme(), GetTestDriver());
gc.OpenPin(InputPin, PinMode.Input);
static void PinChanged(object sender, PinValueChangedEventArgs args)
{
}
for (var i = 0; i < 1000; i++)
{
gc.RegisterCallbackForPinValueChangedEvent(InputPin, PinEventTypes.Rising | PinEventTypes.Falling, PinChanged);
gc.UnregisterCallbackForPinValueChangedEvent(InputPin, PinChanged);
}
}
}
}
......@@ -339,7 +339,7 @@ namespace System.Device.Gpio.Drivers
typeOfEventOccured = e.ChangeType;
}
WaitForEventResult(cancellationToken, eventHandler.CancellationTokenSource.Token, ref eventOccurred);
WaitForEventResult(cancellationToken, eventHandler.CancellationToken, ref eventOccurred);
RemoveCallbackForPinValueChangedEvent(pinNumber, Callback);
return new WaitForEventResult
......
......@@ -12,24 +12,26 @@ namespace System.Device.Gpio.Drivers
{
private const int ERROR_CODE_EINTR = 4; // Interrupted system call
private static string s_consumerName = Process.GetCurrentProcess().ProcessName;
private static readonly string s_consumerName = Process.GetCurrentProcess().ProcessName;
public event PinChangeEventHandler? ValueRising;
public event PinChangeEventHandler? ValueFalling;
private int _pinNumber;
public CancellationTokenSource CancellationTokenSource;
private Task _task;
private bool _disposing = false;
private readonly int _pinNumber;
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly Task _task;
private bool _disposing;
public LibGpiodDriverEventHandler(int pinNumber, SafeLineHandle safeLineHandle)
{
_pinNumber = pinNumber;
CancellationTokenSource = new CancellationTokenSource();
_cancellationTokenSource = new CancellationTokenSource();
SubscribeForEvent(safeLineHandle);
_task = InitializeEventDetectionTask(CancellationTokenSource.Token, safeLineHandle);
_task = InitializeEventDetectionTask(_cancellationTokenSource.Token, safeLineHandle);
}
public CancellationToken CancellationToken => _cancellationTokenSource.Token;
private void SubscribeForEvent(SafeLineHandle pinHandle)
{
int eventSuccess = Interop.libgpiod.gpiod_line_request_both_edges_events(pinHandle, s_consumerName);
......@@ -103,8 +105,17 @@ namespace System.Device.Gpio.Drivers
public void Dispose()
{
_disposing = true;
CancellationTokenSource.Cancel();
_task?.Wait();
_cancellationTokenSource.Cancel();
try
{
_task.GetAwaiter().GetResult();
}
catch (TaskCanceledException)
{
// ignore cancellation exception
}
ValueRising = null;
ValueFalling = null;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册