C#:异步任务:取消
C#: Async Task: Cancel
我有一个函数可以在几秒钟内完成一些工作。我试图在一段时间后取消该任务,但我无法这样做。我的 objective 是执行 asyncFunction 5 秒,然后转到另一个任务。出于某种原因,我似乎无法等待 _t1。
private async Task asyncFunction(string line_1, string line_2, string line_3, string line_4, int _time, System.Threading.CancellationTokenSource _cts)
{
_cts.Token.ThrowIfCancellationRequested();
await Task.Run(async () => {
someFunction_01(line_1, line_2, line_3, line_4);
someFunction_01("HELLO WORLD");
await Task.Delay(_time, _cts.Token);
});
}
我调用函数的方式是:
TimeSpan _timeout = TimeSpan.FromSeconds(5);
var timeoutCancellationTokenSource = new System.Threading.CancellationTokenSource(_timeout);
Task _t1 = asyncFunction("LINE 01", " ", " ", " ", 6000, timeoutCancellationTokenSource);
if (await Task.WhenAny(_t1, Task.Delay(_timeout, timeoutCancellationTokenSource.Token)) == _t1)
{
await _t1;
}
else
{
// timeout/cancellation logic
timeoutCancellationTokenSource.Cancel();
}
我似乎无法取消 asyncFunction 中的 Task.Delay。感谢任何代码帮助。
我不太明白这段代码的用途。特别是 if-statement:
if (await Task.WhenAny(_t1, Task.Delay(_timeout, timeoutCancellationTokenSource.Token)) == _t1)
为什么将 _timeout
传递给 Task.Delay
,这与您创建 timeoutCancellationTokenSource
的超时相同?
如果我们忽略您提供的第一个参数 Task.Delay
这也意味着您使用相同的 CancellationToken
两次调用 Task.Delay
现在您有一个 race-condition 其中无法预测哪个 Task.Delay
会先被取消。
要显示如何使取消生效的示例,您可以这样做:
TimeSpan _timeout = TimeSpan.FromSeconds(1);
var timeoutCancellationTokenSource = new System.Threading.CancellationTokenSource(_timeout);
Task _t1 = asyncFunction("LINE 01", " ", " ", " ", 2000, timeoutCancellationTokenSource);
try
{
await _t1;
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation was cancelled");
}
// Output: Operation was cancelled
如果 _timeout
比传入 asyncFunction
的 2000
毫秒长,任务将在 2 秒后完成而不会被取消。
请参阅 this fiddle 进行测试 运行。
我有一个函数可以在几秒钟内完成一些工作。我试图在一段时间后取消该任务,但我无法这样做。我的 objective 是执行 asyncFunction 5 秒,然后转到另一个任务。出于某种原因,我似乎无法等待 _t1。
private async Task asyncFunction(string line_1, string line_2, string line_3, string line_4, int _time, System.Threading.CancellationTokenSource _cts)
{
_cts.Token.ThrowIfCancellationRequested();
await Task.Run(async () => {
someFunction_01(line_1, line_2, line_3, line_4);
someFunction_01("HELLO WORLD");
await Task.Delay(_time, _cts.Token);
});
}
我调用函数的方式是:
TimeSpan _timeout = TimeSpan.FromSeconds(5);
var timeoutCancellationTokenSource = new System.Threading.CancellationTokenSource(_timeout);
Task _t1 = asyncFunction("LINE 01", " ", " ", " ", 6000, timeoutCancellationTokenSource);
if (await Task.WhenAny(_t1, Task.Delay(_timeout, timeoutCancellationTokenSource.Token)) == _t1)
{
await _t1;
}
else
{
// timeout/cancellation logic
timeoutCancellationTokenSource.Cancel();
}
我似乎无法取消 asyncFunction 中的 Task.Delay。感谢任何代码帮助。
我不太明白这段代码的用途。特别是 if-statement:
if (await Task.WhenAny(_t1, Task.Delay(_timeout, timeoutCancellationTokenSource.Token)) == _t1)
为什么将 _timeout
传递给 Task.Delay
,这与您创建 timeoutCancellationTokenSource
的超时相同?
如果我们忽略您提供的第一个参数 Task.Delay
这也意味着您使用相同的 CancellationToken
两次调用 Task.Delay
现在您有一个 race-condition 其中无法预测哪个 Task.Delay
会先被取消。
要显示如何使取消生效的示例,您可以这样做:
TimeSpan _timeout = TimeSpan.FromSeconds(1);
var timeoutCancellationTokenSource = new System.Threading.CancellationTokenSource(_timeout);
Task _t1 = asyncFunction("LINE 01", " ", " ", " ", 2000, timeoutCancellationTokenSource);
try
{
await _t1;
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation was cancelled");
}
// Output: Operation was cancelled
如果 _timeout
比传入 asyncFunction
的 2000
毫秒长,任务将在 2 秒后完成而不会被取消。
请参阅 this fiddle 进行测试 运行。