在这里,您可以采用 2 种不同的方式,我将在下面发布这两个选项,以帮助您指明正确的方向
您应该在另一个线程上执行此操作,然后从该线程更新您的 UI 线程。您正在通过在 UI 线程上执行此工作来阻止进一步的处理。
如果您不能将此代码移动到 UI 线程,那么您可以随时调用Application.DoEvents
,但我强烈建议您先探索这些选项:
第二种选择你可以做这样的事情:
您需要将数据从一个线程传输到另一个线程。这可以通过几种方式完成......
首先,您的“背景”线程可以更新某种“CurrentStatus”字符串变量,它会随着它的进行而改变。然后,您可以在表单上放置一个计时器,然后获取 CurrentStatus 变量并使用它更新标签。
其次,您可以使用标签控件的 InvokeRequired 属性通过委托简单地将操作从后台线程调用到 UI 线程。所以例如...
private delegate void UpdateStatusDelegate(string status);
private void UpdateStatus(string status)
{
if (this.label1.InvokeRequired)
{
this.Invoke(new UpdateStatusDelegate(this.UpdateStatus), new object[] { status });
return;
}
this.label1.Text = status;
}
您可以从任何线程(UI 或后台)调用该 UpdateStatus() 方法,它会检测是否需要在主 UI 线程上调用操作(如果需要,是否需要)。
编辑:要实际设置线程,您可以这样做:
private void StartProcessing()
{
System.Threading.Thread procThread = new System.Threading.Thread(this.Process);
procThread.Start();
}
private void Process() // this is the actual method of the thread
{
foreach (System.IO.FileInfo f in dir.GetFiles("*.txt"))
{
// Do processing
// Show progress bar
// Update Label on Form, "f.Name is done processing, now processing..."
UpdateStatus("Processing " + f.Name + "...");
}
}
然后,当用户单击“开始”按钮时,您只需调用 StartProcessing()。