【发布时间】:2016-01-26 17:03:09
【问题描述】:
我有以下代码在后台线程中使用经过时间更新标签。在通过按下按钮模拟的主 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;
}
}
}
}
【问题讨论】:
-
阻止用户在 WinForms 中执行某些操作的简单解决方案是使用 FormDialog,它将接管应用程序,直到它被隐藏或关闭。在这种情况下,当按下按钮时,只需 someForm.ShowDialog() 插入 someForm.Show() (模态与非模态),一旦 bgw 工作人员完成,只需取消隐藏关闭按钮。
-
SpaceSteak 的想法很可能是您想要的方式。另一种选择是简单地禁用您不希望用户在您工作时使用的任何按钮/控件。
-
SpaceSteak,不确定这是否是解决方案,因为在我的情况下,按下按钮时完成的工作也是使用 GUI 在输出窗口中打印内容。我的应用程序是 2 个树视图,我在它们之间拖放(正在完成的工作并打印到输出窗口)+ 一个带有计时器的标签,显示工作完成时经过的时间。
-
底线是您不能使用 UI 来执行长时间运行的过程,因为一切都会冻结 - 甚至更新。所以 button1_click 中的代码需要进入异步任务
标签: c# multithreading timer