如何在C#Winforms应用程序中取消长时间运行的异步任务的执行

我是一个相当缺乏经验的c#程序员,需要帮助来管理我的程序流程.它是一个WinFormApp,它要求多个用户输入,然后使用它们与设备建立串行通信以进行测量.测量是在异步方法中进行的,运行大约需要20分钟.所以我正在使用

    void main()
    {
        //Setup
    }

    private void button1_Click(object sender, EventArgs e)
    {
        await measurements();
        //Plot results
    }

    private async Task measurements()
    {
        while(true){
        //Make some measurements
        await Task.Delay(120000);
        //Make measurements, present data in the UI form.
        //return if done
        }
    }

现在我需要创建一个按钮,使用户可以取消测量,以便更改某些输入或参数,然后重新开始测量.所以我添加了一个“取消”按钮.

    private void button7_Click(object sender, EventArgs e)
    {
        textBox64.Enabled = true;
        button6.Enabled = true;
        button5.Enabled = true;
        textBox63.Enabled = true;
        button3.Enabled = true;
        trackBar1.Enabled = true;
        timer.Enabled = true;
        button7.Enabled = false;
        clearData();
        // measurement.Stop();            
    }

现在我不知道如何管理程序的流程.我试图在button1_Click()中创建一个try-catch结构,并从button7_Click中抛出一个Exception,但它没有通过button1_Click().
然后我尝试在新线程上运行测量().但是线程无法访问我主表单上的70-ahh UI项目.
甚至我也不会像尝试Goto一样低沉.

我需要的是关于如何在这种情况下编程的建议,以便很好地控制应用程序,而不是像异常和Goto那样危及程序流程.

最佳答案
如果要在中途取消实际任务,则需要查看使用CancellationTokenSource并将取消令牌传递到异步方法.

This is the Microsoft documentation在底部和this is another good blog附近有一个很好的例子,显示进度条并允许取消.第二篇文章有一个很好的概述:

Cancellation is controlled by the CancellationToken structure. You
expose cancellation tokens in the signature of cancelable async
methods, enabling them to be shared between the task and caller. In
the most common case, cancellation follows this flow:

  1. The caller creates a CancellationTokenSource object.
  2. The caller calls a cancelable async API, and passes the
    CancellationToken from the CancellationTokenSource
    (CancellationTokenSource.Token).
  3. The caller requests cancellation using the CancellationTokenSource
    object (CancellationTokenSource.Cancel()).
  4. The task acknowledges the cancellation and cancels itself, typically
    using the CancellationToken.ThrowIfCancellationRequested method.

为了使您的应用能够快速响应取消请求,您需要在长时间运行的方法中定期检查取消令牌,并在请求取消时对其做出相应的响应.

转载注明原文:如何在C#Winforms应用程序中取消长时间运行的异步任务的执行 - 代码日志