从单独的线程访问表单的控件

时间:2011-09-30 11:42:48

标签: c# winforms multithreading

我正在练习线程并遇到了这个问题。情况是这样的:

  1. 我在一个表单上有4个进度条,一个用于下载文件,一个用于显示页面加载状态等...

  2. 我必须从一个单独的线程控制每个ProgressBar的进度。

  3. 问题是我得到 InvalidOperationException ,其中说

      

    跨线程操作无效:从中访问控制'progressBar1'   一个线程,而不是它创建的线程。

    我在这种方法上是错的还是有人能告诉我如何实现这个?

5 个答案:

答案 0 :(得分:41)

Control只能在创建它的线程中访问 - UI线程。

您必须执行以下操作:

Invoke(new Action(() =>
{
    progressBar1.Value = newValue;
}));

然后,invoke方法在UI线程上执行给定的委托。

答案 1 :(得分:12)

您可以检查Control.InvokeRequired标志,然后根据需要使用Control.Invoke方法。 Control.Invoke接受委托,因此您可以使用内置的Action< T>。

public void UpdateProgress(int percentComplete)
{
   if (!InvokeRequired)
   {
      ProgressBar.Value = percentComplete;
   }
   else
   {
      Invoke(new Action<int>(UpdateProgress), percentComplete);
   }
}

答案 2 :(得分:9)

UI元素只能由UI线程访问。 WinForms和WPF / Silverlight不允许从多个线程访问控件。

A work-around to this limitation can be found here

答案 3 :(得分:6)

 private void Form1_Load(object sender, EventArgs e)
    {
        CheckForIllegalCrossThreadCalls = false;
    }

也许这会奏效。

答案 4 :(得分:2)

您需要从非UI线程调用方法Invoke,以在表单和其他控件上执行某些操作。