37

在处理时更新 Windows 窗体应用程序上的标签的最佳方法是什么?

当用户单击按钮时,我有一个循环对用户系统上的文件进行一些处理。

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..."
}

什么是一些示例代码?

这到底叫什么?是线程还是委托?

4

5 回答 5

70

一个快速的解决方法是:

Label1.Text = f.Name + " is done processing, now processing...";
Label1.Refresh();

您真的想避免DoEvents,否则如果您的用户反复按下表单上的按钮,您将遇到问题。

于 2009-02-20T17:42:13.060 回答
14

应该在另一个线程上执行此操作,然后从该线程更新您的 UI 线程。您正在通过在 UI 线程上执行此工作来阻止进一步的处理。

如果您不能将此代码移动到 UI 线程,那么您可以随时调用Application.DoEvents,但我强烈建议您先探索这些选项:

于 2009-02-20T17:38:06.427 回答
13

您需要将数据从一个线程传输到另一个线程。这可以通过几种方式来完成......

首先,您的“背景”线程可以更新某种“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()。

于 2009-02-21T15:57:37.673 回答
1

如果您的处理时间很长,请在后台工作线程中进行。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

于 2009-02-20T17:37:31.667 回答
1

我还建议使用:

Application.DoEvents();

处理当前在消息队列中的所有 Windows 消息。

于 2019-03-14T09:23:51.283 回答