关于多线程:c#线程访问其他线程

c# threading access to other thread

本问题已经有最佳答案,请猛点这里访问。

我有一个错误:跨线程操作无效:"从创建它的线程以外的线程访问控件"progressbar1",我似乎不知道如何修复它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    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);
        }
    }

试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的值。


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

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

只有当progressBar1.InvokeRequired是真的时,你才必须这样做。考虑使用这个扩展类(无耻的自我提升,抱歉)。然后您可以忘记您是否在正确的线程上:

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


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

有关详细信息,请参阅控件调用

试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
   }
}