我需要重新进入任务,并将类似的代码实现到https://blogs.msdn.microsoft.com/lucian/2014/03/03/async-re-entrancy-and-the-patterns-to-deal-with-it/(模式5)
但是我想知道CancellationTokenSource配置是否没有丢失。我的实现是将它添加到.ContinueWith
中 private Task _fooAsyncTask;
private CancellationTokenSource _fooAsyncCancellation;
public async Task Button1Click()
{
// Assume we're being called on UI thread... if not, the two assignments must be made atomic.
// Note: we factor out "FooHelperAsync" to avoid an await between the two assignments.
// without an intervening await.
_fooAsyncCancellation?.Cancel();
_fooAsyncCancellation = new CancellationTokenSource();
_fooAsyncTask = FooHelperAsync(_fooAsyncCancellation.Token);
await _fooAsyncTask.ContinueWith(task =>
{
_fooAsyncCancellation.Dispose();
_fooAsyncCancellation = null;
});
}
private async Task FooHelperAsync(CancellationToken cancel)
{
try { if (_fooAsyncTask != null) await _fooAsyncTask; }
catch (OperationCanceledException) { }
cancel.ThrowIfCancellationRequested();
await FooAsync(cancel);
}
private async Task FooAsync(CancellationToken cancel)
{
//
}
这是对的吗?
答案 0 :(得分:0)
您应该将代码更改为
fooAsyncCancellation
设置为null
(续接时不是)这里是修改后的代码
Task _fooAsyncTask;
CancellationTokenSource _fooAsyncCancellation;
async void button1_Click(object sender, EventArgs e)
{
_fooAsyncCancellation?.Cancel();
using (var cts = new CancellationTokenSource())
{
_fooAsyncCancellation = cts;
try
{
await FooAsyncHelper(cts.Token);
}
catch (OperationCanceledException) { }
if (_fooAsyncCancellation == cts)
{
_fooAsyncCancellation = null;
}
}
}
async Task FooAsyncHelper(CancellationToken cancellationToken)
{
try
{
if (_fooAsyncTask != null)
{
await _fooAsyncTask;
}
}
catch (OperationCanceledException) { }
cancellationToken.ThrowIfCancellationRequested();
await FooAsync(cancellationToken);
}
async Task FooAsync(CancellationToken cancellationToken)
{
// just some sample work to do
for (int i = 0; i < 100; i++)
{
await Task.Delay(100);
cancellationToken.ThrowIfCancellationRequested();
}
}