我有以下代码更新标签,其中包含后台线程中的已用时间。我想在按下按钮模拟的主UI线程上做大量工作时继续这样做。我想让UI保持忙碌,以便用户无法完成其他操作。怎么办呢?
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private BackgroundWorker _worker;
Stopwatch _watch = null;
public Form1()
{
InitializeComponent();
InitWorker();
_watch = Stopwatch.StartNew();
}
private void InitWorker()
{
if (_worker != null)
{
_worker.Dispose();
}
_worker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_worker.DoWork += DoWork;
_worker.RunWorkerAsync();
}
void DoWork(object sender, DoWorkEventArgs e)
{
while (_watch != null)
{
label1.Invoke((MethodInvoker)delegate
{
label1.Text = _watch.Elapsed.ToString(@"hh\:mm\:ss");
});
Thread.Sleep(1000);
}
}
private void button1_Click(object sender, System.EventArgs e)
{
for (int i = 0; i < 1000000000; i++)
{
double a = 600000000000000.5;
a = a / 4.54;
}
}
}
}
答案 0 :(得分:0)
只要您阻止UI线程,UI就会被冻结,就不能处理任何Invoke(它们怎么可能?它们将代码编组到忙线的UI线程中。)
此策略无效。
如果要阻止UI,请不要冻结它。您可能应该禁用您关心的所有输入元素。一个根本的解决方案是将透明面板覆盖在表单的整个客户区域上。但这对用户来说很奇怪。
如果你不知道:你可以使用await Task.Run(...);
轻松地在后台线程上运行昂贵的工作。 BackgroundWorker
已过时。