【问题标题】:Cancel Task method in C# [duplicate]C#中的取消任务方法[重复]
【发布时间】:2015-09-28 18:31:38
【问题描述】:

我的视图模型中有这样的异步方法

public async Task Download()
{
//Do some background thread to do heavywork and recursive task
await Download();
}

那我这样叫我的观点

private async Task LoadData()
{
_vm.Download();
//Do other background task
await _vm.DoElse();
}

然后这样称呼它

Task.Factory.StartNew(async()=> {await LoadData();});

现在我的问题是如何取消Download()

【问题讨论】:

  • 不应该是await _vm.Download();吗?您的代码甚至可以正常工作吗?因为如果我没记错的话,_vb.DoElse 会立即被调用。
  • 取消令牌是您所需要的。示例可以在here 找到。是的,当前_vm.Download(); 正在阻塞您的线程,因此您将无法取消。

标签: c# async-await


【解决方案1】:

你应该传递给异步方法CancellationToken

那么你应该在每次迭代时检查它:

public async Task Download(CancellationToken cancellationToken)
{
    if (cancellationToken.IsCancellationRequested)
    {
        //Do work on cancel
        return;
    }
    //Do some background thread to do heavywork and recursive task
    await Download();
}

要在外面取消它,你应该在CancellationTokenSource对象之外的地方处理,当你想取消时,只需调用_cancellationTokenSource.Cancel()

Task.Factory.StartNew(async()=> {await LoadData(_cancellationTokenSource.Token);});

private async Task LoadData(CancellationToken cancellationToken)
{
    await _vm.Download(cancellationToken);
    //Do other background task
    await _vm.DoElse(cancellationToken);
}

【讨论】:

  • 可以,使用CancellationToken,但是不行,不要勾选IsCancellationRequested,然后正常返回。请改用cancellationToken.ThrowIfCancellationRequested()。这使用了一个异常,导致上级调用者也自动取消,除非他们特别选择以不同的方式处理取消,并清楚地向调用者表明任务没有正常完成。
  • 难道你不应该token.ThrowIfCancellationRequested(); 而不是在if (cancellationToken.IsCancellationRequested) 内返回吗?
  • 这取决于您需要的行为。如果要在调用堆栈中捕获此异常上层,可以使用 token.ThrowIfCancellationRequested()。如果正常的话,那个任务可以静默取消,这个方案不错。在我的代码中,我使用这两种情况取决于要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多