我编写了一个计数程序,该值在标签的文本中表示。 单击按钮启动该过程。 当我开始时,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));
}
}
}
答案 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#中引入的async
和await
关键字,它们将在后台执行额外的工作,而不是在UI线程上,目前所有处理都在UI线程上完成,这会导致UI线程被阻止。但是在你的情况下不会产生影响,因为这里的问题是更快地更新UI,导致它冻结。
答案 1 :(得分:0)
它会阻止,因为您在与UI相同的线程上运行它。此外,对标签的许多更新也不会完全正常 - 即使从另一个线程更新。
如果您真的想这样做,请创建一个新的线程/任务并从那里正确调用UI更新。
答案 2 :(得分:0)
因为您在UI-Thread上执行此操作。请尝试使用Task.Run()
代替BeginInvoke()
。