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

标签 c# multithreading exception return goto

我是一个经验不足的 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 中抛出异常,但它没有通过button1_Click().
然后我尝试在新线程上运行 measurements()。但是线程无法访问我的主窗体上的 70 多个 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.

为了使您的应用快速响应取消请求,您需要在长期运行的方法中定期检查取消 token ,并在请求取消时相应地响应它。

关于c# - 如何取消在 C# Winforms 应用程序中执行长时间运行的异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35060647/

相关文章:

c# - TLSharp - 有人有例子吗?

c# - 具有命名空间限制的通用类型

c# - 如何为 Web API 2 异步操作中的异常获取正确的堆栈跟踪?

c# - 为什么 n.GetHashCode() 有效但 n.GetType() 抛出异常?

c++ - 清除 C++ 异常的析构函数中的代码

c# - 使用 ODBC 进行 Entity Framework 连接

c# - 无法在单元测试中复制 'cross-thread operation not valid' 错误 - 我不明白

c - 如何设置和管理持久多线程?

c++ - Objective-C 或 Objective C++ 可以处理 C++ 异常吗?

java - 如何确保我的线程/进程在不同的内核上运行