取消任务并将状态设置为 "Cancelled"
Cancel Task and set status to "Cancelled"
我希望任务在 50 毫秒结束时完成。然后应将任务的状态设置为“Cancelled”,否则设置为“RunToCompletion”。
任务创建在这里:
CancellationTokenSource cts = new CancellationTokenSource(50);
CancellationToken ct = cts.Token;
Task test_task = Task.Run(async () =>
{
try
{
tokenS.Token.Register(() =>
{
cts.Cancel();
ct.ThrowIfCancellationRequested();
});
await NotifyDevice(BLEDevice);
}
catch (Exception e)
{
}
},ct);
我现在得到的只是一个 AggregateException
,它不会以某种方式被 try/catch
-block 捕获。
这里有一个与您类似的问题:Is it possible to cancel a C# Task without a CancellationToken?. But the solution will not cancel the task in NotifyDevice
method. That task can be cancelled only if underlying task supports cancellation. And based on the docs IAsyncInfo 可以取消。如果取消基础任务需要更多时间,我会使用包装器以确保在 50 毫秒内取消任务:
CancellationTokenSource cts = new CancellationTokenSource(50);
await NotifyDevice(BLEDevice, cts.Token).WithCancellation(cts.Token);
编辑: 扩展方法本身:
public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using(cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
return await task;
}
我希望任务在 50 毫秒结束时完成。然后应将任务的状态设置为“Cancelled”,否则设置为“RunToCompletion”。
任务创建在这里:
CancellationTokenSource cts = new CancellationTokenSource(50);
CancellationToken ct = cts.Token;
Task test_task = Task.Run(async () =>
{
try
{
tokenS.Token.Register(() =>
{
cts.Cancel();
ct.ThrowIfCancellationRequested();
});
await NotifyDevice(BLEDevice);
}
catch (Exception e)
{
}
},ct);
我现在得到的只是一个 AggregateException
,它不会以某种方式被 try/catch
-block 捕获。
这里有一个与您类似的问题:Is it possible to cancel a C# Task without a CancellationToken?. But the solution will not cancel the task in NotifyDevice
method. That task can be cancelled only if underlying task supports cancellation. And based on the docs IAsyncInfo 可以取消。如果取消基础任务需要更多时间,我会使用包装器以确保在 50 毫秒内取消任务:
CancellationTokenSource cts = new CancellationTokenSource(50);
await NotifyDevice(BLEDevice, cts.Token).WithCancellation(cts.Token);
编辑: 扩展方法本身:
public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using(cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
return await task;
}