停止产生线程

时间:2015-06-30 21:17:22

标签: c# multithreading asynchronous

在Windows窗体中使用以下代码。

    private bool test = false;

    private async void button1_Click(object sender, EventArgs e)
    {
        await Task.Run(() =>
        {
            test = !test ;
            textBox2.Text = test.ToString(); // Each time i click text box switches to true and false
            for (int i = 0; i < 1000000; i++)
            {
                textBox1.Text = i.ToString();
            }
        });

       textBox2.Text = "Done"; // This will never happen until the task is done
    }

如果我单击按钮,文本框文本将从0更改为1000000。

因为我使用async / await。表单不会冻结,我可以看到文本框计数从0到1000000。

但问题是,如果我再次单击该按钮,另一个线程生成和文本框值将由两个线程更改。你可以看到两个线程改变文本框值的两个计数器。

如果再次点击,你会得到3个主题,4个主题等等....另外textbox2也会变为true,false,true ....

这对我来说只是一个测试,看看实际异步等待是如何工作的。

但我认为我错了。我担心如果我在我的项目中使用异步并结束这种情况。

如何从单一异步方法中停止产生线程。

  

目前我认为每次按下按钮New async Method都会产生。

这就是我所看到的。

enter image description here

2 个答案:

答案 0 :(得分:1)

关于正在发生的事情的评论中存在一些混淆。特别是因为发布的代码实际上不起作用(它不是线程安全的)。

重现此方法的最简单方法(在表单上删除Button和Label):

private async void button1_Click(object sender, EventArgs e)   // add the async
{
    for (int i = 0; i < 1000; i++)
    {
        label1.Text = "" + i;
        await Task.Delay(100);
    }
}

您可以让它一次运行多个循环,您可以增加延迟以更好地查看。请注意,没有涉及额外的线程,它都在主GUI线程上运行。

这里的密钥是asyncawait,它们使编译器将对此方法的调用转换为状态机,这样它就可以一次交错执行多个循环。可以将其视为可以在await调用时暂停并稍后恢复的方法。所有都在同一个线程上。

更重要的是,它将循环与主线程交错,以便继续处理输入消息并更新屏幕。

那是“为什么”的一部分。

如何解决它的部分取决于你真正想要的,@ CSharpie现在删除的答案显示基本模式:使用布尔字段作为保护,或禁用&amp;启用按钮。

答案 1 :(得分:0)

按下后禁用按钮,并在完成后启用它。

相关问题