c#threading访问其他线程

时间:2013-04-10 17:47:33

标签: c# multithreading winforms

我有这个错误:跨线程操作无效:“从创建它的线程以外的线程访问控制'progressBar1'。”我似乎无法弄清楚如何解决它。

    private void button1_Click(object sender, EventArgs e)
    {
        this.panel1.Visible = false;
        this.panel2.Visible = true;
        new Thread(ProgressBAR).Start();
    }
    private void ProgressBAR()
    {
        Thread.Sleep(5);
        for (int start = 0; start <= 100; start++)
        {
            this.progressBar1.Value = start;
            Thread.Sleep(5);
        }
    }

3 个答案:

答案 0 :(得分:3)

试试这个:

private void button1_Click(object sender, EventArgs e)
{
    this.panel1.Visible = false;
    this.panel2.Visible = true;
    new Thread(ProgressBAR).Start();
}

private void ProgressBAR()
{
    Thread.Sleep(5);
    for (int start = 0; start <= 100; start++)
    {
        this.Invoke(new Action(() => this.progressBar1.Value = start));
        Thread.Sleep(5);
    }
}

由于操作系统的限制,您无法从创建它的线程以外的任何线程访问UI元素。对Invoke的调用将同步调用调用以更新主线程上的ProgressBar值。

答案 1 :(得分:2)

您需要使用进度条的Invoke方法在控件的主线程上执行赋值:

this.progressBar1.Invoke((Action) () => this.progressBar1.Value = start, null);

progressBar1.InvokeRequired为真时,您只需执行此操作。考虑使用this extension class(无耻的自我推销,抱歉)。然后你可以忘记你是否在正确的线程上:

this.progressBar1.AutoInvoke(() => this.ProgressBar1.Value = start);

答案 2 :(得分:-1)

您必须在拥有控件的基础窗口句柄的线程上执行指定的委托。

有关详细信息,请参阅 Control.Invoke

试试这个:

private void button1_Click(object sender, EventArgs e)
{
   this.panel1.Visible = false;
   this.panel2.Visible = true;
   new Thread(ProgressBAR).Start();
}

private void ProgressBAR()
{
   Thread.Sleep(5);
   for (int start = 0; start <= 100; start++)
   {
      this.Invoke(new Action(() => this.progressBar1.Value = start));
      Thread.Sleep(5);
   }
}