调用委托方法会阻止我的C#app

时间:2016-02-15 16:31:02

标签: c# delegates

我编写了一个计数程序,该值在标签的文本中表示。 单击按钮启动该过程。 当我开始时,UI冻结。 我想由代表解决。 我的臭虫在哪里?

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication6
{

    public delegate void MyDelegate();
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void DelegateMethod()
        {


            for (int i = 0; i < 9999999999999; i++)
            {
                label1.Text = i.ToString();

            }
            MessageBox.Show("OK");

        }

        private void button1_Click(object sender, EventArgs e)
        {
            BeginInvoke(new MyDelegate(DelegateMethod));
        }
    }
}

3 个答案:

答案 0 :(得分:1)

这是因为您的UI元素如此频繁地更新,并且它将继续执行直到循环终止,如果您在每次迭代后添加Thread.Sleep(),您可以看到行为不同:

for (int i = 0; i < 9999999999999; i++)
{
    label1.Text = i.ToString();
    // for example delay 1 second
    Thread.Sleep(1000);

}

更好的方法是使用c#中引入的asyncawait关键字,它们将在后台执行额外的工作,而不是在UI线程上,目前所有处理都在UI线程上完成,这会导致UI线程被阻止。但是在你的情况下不会产生影响,因为这里的问题是更快地更新UI,导致它冻结。

答案 1 :(得分:0)

它会阻止,因为您在与UI相同的线程上运行它。此外,对标签的许多更新也不会完全正常 - 即使从另一个线程更新。

如果您真的想这样做,请创建一个新的线程/任务并从那里正确调用UI更新。

答案 2 :(得分:0)

因为您在UI-Thread上执行此操作。请尝试使用Task.Run()代替BeginInvoke()