通过单击按钮取消带有 CancellationTokenSource 的异步任务不起作用

Posted

技术标签:

【中文标题】通过单击按钮取消带有 CancellationTokenSource 的异步任务不起作用【英文标题】:Cancel Async Task with CancellationTokenSource from a button click not working 【发布时间】:2021-05-01 09:48:12 【问题描述】:

我需要做的是能够取消正在异步运行的任务。单击取消按钮时应取消任务。我已经用CancellationTokenSource 做到了。但它不能正常工作。

public class classA 

    CancellationTokenSource _tokenSource = null;

    public void OnCancelButtonClick()
    
        MessageBox.Show("Do you Really want to cancel upload");            
        _tokenSource = new CancellationTokenSource();
        _tokenSource.Cancel();
    

    public async void UploadBtnClick(object param )
    
        _tokenSource = new CancellationTokenSource();
        var token = _tokenSource.Token;
        try
        
            await Task.Run(() => UploadFunction(token));
        
        catch(OperationCanceledException ex)
        
            MessageBox.Show(ex.Message);

        
        finally
        
            _tokenSource.Dispose();
        
    

    public Task<bool> UploadFunction(CancellationToken token)
    
        foreach
        
            //code here

            if (token.IsCancellationRequested)
            
                token.ThrowIfCancellationRequested();
            
                  
    

我正在从另一个函数调用OnCancelButtonClick

public class classB 

    public void CancelUploadBtnExecute(object param)
    
        FilesViewModel vm = new FilesViewModel();
        vm.OnCancelButtonClick(); 
    

当我点击 OnCancelButtonClick 时,IsCancellationRequestedfalse,但不会反映在 UploadFunction 中,因此任务不会停止。

【问题讨论】:

【参考方案1】:

这是因为您在 OnCancelButtonClick() 中初始化新的 CancellationTokenSource

只需从OnCancelButtonClick()中删除此行

_tokenSource = new CancellationTokenSource();

UploadFunction 方法正在使用CancellationTokenSourceUploadBtnClick 方法中创建的令牌。

【讨论】:

System.NullReferenceException: '对象引用未设置为对象的实例。' _tokenSource 为空。 @developer OnCancelButtonClick 方法有异常吗?如果是,则添加检查 if(_tokenSource!=null)。 是 OnCancelButtonClick 方法中的异常 @developer 在 OnCancelButtonClick 之前调用 UploadBtnClick 时,根据您共享的代码,_tokenSource 不能为空。 @developer 您是否从调用 OnCancelButtonClick 的同一类中调用 UploadBtnClick?如果 UploadBtnClick 和 OnCancelButtonClick 不是从同一个类中调用的,那么您必须确保在 classA 的同一个实例上调用 UploadBtnClick 和 OnCancelButtonClick。

以上是关于通过单击按钮取消带有 CancellationTokenSource 的异步任务不起作用的主要内容,如果未能解决你的问题,请参考以下文章

SearchBar 在单击取消按钮之前不显示结果

如何通过单击 QProgressDialog 的取消按钮来取消 QProcess?

在两个同步任务之间捕获取消按钮单击

单击 UISearchBar 的取消按钮后,如何使用 UISearchBar 刷新我的 UITableView?

带有actionListeners的多个选择列表?

Python如何在循环中证明布尔表达式并在单击按钮时取消循环