将取消令牌添加到具有进度的异步任务

Jib*_*hew 5 c# task async-await cancellationtokensource cancellation-token

我正在使用下面的代码以WPF页面异步方式进行耗时的操作,并向UI报告进度

    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
        txt_importStatus.Text = "";
        var progress = new Progress<string>(progress_info =>
        {
            //show import progress on a textfield
            txt_importStatus.Text = progress_info + Environment.NewLine + "Please dont close this window while the system processing the excel file contents";              
        });
        // DoProcessing is run on the thread pool.
        await Task.Run(() => DoProcessing(progress));
    }

    public void DoProcessing(IProgress<string> progress)
    {

        //read an excel file and foreach excel file row
        foreach(excelrow row in excelrowlist)
        {
            //do db entry and update UI the progress like 
            progress.Report("Processed x number of records. please wait..");    
        }  
    }
Run Code Online (Sandbox Code Playgroud)

现在我想在中间添加一个取消此异步操作的额外选项。为此,我发现我必须添加以下选项

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;    
private void btnCacnel_Click(object sender, RoutedEventArgs e)
{
    tokenSource.Cancel();
}
Run Code Online (Sandbox Code Playgroud)

但是我如何将这个tokenSource传递给我的DoProcessing调用,以及如何处理DoProcessing内部的取消

mar*_*ian 3

实际上,您不需要传递CancellationTokenSourceto DoProcessing,而只需传递CancellationToken.

为了处理取消,你可以这样做:

    public void DoProcessing(CancellationToken token, IProgress<string> progress)
    {
        //read an excel file and foreach excel file row
        foreach(excelrow row in excelrowlist)
        {
            if(token.IsCancellationRequested)
                break;

            //do db entry and update UI the progress like 
            progress.Report("Processed x number of records. please wait..");    
        }  
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您需要在 中创建取消令牌源btnStart_Click。如果不清楚,您需要这样做:

    CancellationTokenSource tokenSource;

    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
        txt_importStatus.Text = "";
        var progress = new Progress<string>(progress_info =>
        {
            //show import progress on a textfield
            txt_importStatus.Text = progress_info + Environment.NewLine + "Please dont close this window while the system processing the excel file contents";              
        });
        // DoProcessing is run on the thread pool.
        tokenSource = new CancellationTokenSource();
        var token = tokenSource.Token;
        await Task.Run(() => DoProcessing(token, progress));
    }
Run Code Online (Sandbox Code Playgroud)