如何取消长时间运行的异步任务的执行,在C#的WinForms应用 [英] How to cancel execution of a long-running async task in a C# Winforms app

查看:231
本文介绍了如何取消长时间运行的异步任务的执行,在C#的WinForms应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个很没有经验的C#程序员,需要在管理我的程序的流程有所帮助。它是要求多个用户输入一个Wi​​nFormApp然后使用它们来建立与设备,以便使测量的串行通信。测量是在大约需要20分钟来运行异步方法制成。所以我用



 无效的主要()
{
//设置
}

私人无效的button1_Click(对象发件人,EventArgs五)
{
等待测量();
//叠加导致
}

私人异步任务测量()
{
,而(真){
//做一些测量
等待Task.Delay(120000);
//使在UI形式测量,目前的数据。
//返回如果做
}
}

现在我需要做出一个按钮,使用户能够取消,以便改变某些输入或参数,然后重新启动测量的测量。所以我增加了一个取消按钮。

 私人无效button7_Click(对象发件人,EventArgs五)
{
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();
}

现在我不知道如何管理程序的流程。我试图做一个的try-catch 结构的button1_Click() button7_Click ,但它不打通的button1_Click()。结果
然后我试图运行测量()上一个新的线程。但是,线程没有进入70上下的UI项我的主要形式。结果
连我不会下沉低至试图转到。



我需要的是你将如何在这种情况下方案,以便获取应用程序的一个很好的控制,而不是像危险的东西,损害程序的流程咨询例外和后藤。


解决方案

如果您希望通过再取消实际任务中途你需要看看使用CancellationTokenSource和传球一个取消标记到您的异步方法。



这是具有接近底部一个很好的例子和的 =http://blogs.msdn.com/b/ DOTNET /存档/ 2012/06/06 /异步功能于4-5启用-进度和取消功能于异步apis.aspx相对=nofollow>这是另一个不错的博客上显示进度条,并允许注销。这第二篇文章有一个很好的概述:




取消是由结构的CancellationToken控制。你
揭露取消标记在取消异步
方法的签名,使他们能够将任务和来电之间共享。在
最常见的情况,取消遵循以下流程:




  1. 来电者创建一个CancellationTokenSource对象

  2. 的呼叫者呼叫取消异步API,并从CancellationTokenSource
    (CancellationTokenSource.Token)传递
    的CancellationToken。

  3. 呼叫者使用要求取消在CancellationTokenSource
    对象(CancellationTokenSource.Cancel())。

  4. 任务确认取消和取消本身,通常使用的方法CancellationToken.ThrowIfCancellationRequested




为使您的应用程序快速响应,你需要再令牌定期检查取消在长取消请求运行方式,如果取消已要求其作出相应的反应。


I'm a quite inexperienced c# programmer and need help on managing the flow of my program. It is a WinFormApp that asks for multiple user inputs and then uses them to establish serial communication with a device in order to make measurements. The measurements are made in an async method that takes about 20 minutes to run. So I'm using

    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
        }
    }

Now I need to make a button which enables the user to cancel the measurements in order to change some input or parameter and then restart the measurements. So I added a "Cancel"-button.

    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();            
    }

Now I do not know how to manage the flow of the program. I have tried to make a try-catch structure in button1_Click() and throw an Exception from button7_Click, but it doesn't get through to button1_Click().
Then I tried to run measurements() on a new thread. But the thread does not have access to 70-ish UI items on my main form.
And even I wont sink as low as trying Goto.

What I need is advice on how you would program in this situation in order to get a good control of the application and not compromise the flow of the program with risky stuff like exceptions and Goto.

解决方案

If you want to cancel the actual task midway through then you need to look at using a CancellationTokenSource and passing a cancellation token into your async method.

This is the Microsoft documentation on that which has a good example near the bottom and this is another good blog on showing a progress bar and allowing cancellation. that second article has a good overview:

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.

To make your app respond quickly to a cancel request you need to then check the cancellation token regularly in your long running method and respond to it accordingly if a cancellation has been requested.

这篇关于如何取消长时间运行的异步任务的执行,在C#的WinForms应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆