2013-04-10 105 views
1

我有這個錯誤:跨線程操作無效:「控制'progressBar1'從其創建的線程以外的線程訪問」。我似乎無法弄清楚如何解決它。c#線程訪問其他線程

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); 
     } 
    } 

回答

2

您需要使用進度條的Invoke方法來控制的主線程上執行任務:

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

progressBar1.InvokeRequired爲真時,您只需要執行此操作。考慮使用this extension class(無恥的自我推銷,對此感到抱歉)。那麼你可以忘記你是否在正確的線程:

this.progressBar1.AutoInvoke(() => this.ProgressBar1.Value = start); 
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

您必須在擁有控件底層窗口句柄的線程上執行指定的委託。

欲瞭解更多信息,請參閱 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); 
    } 
} 
+0

謝謝,它完美的作品。 – user2267264 2013-04-10 17:52:25

+2

沒有相應的'EndInvoke'調用'BeginInvoke'就是一個bug,**會泄漏內存**。 – cdhowie 2013-04-10 17:53:12

+0

@cdhowie:編輯調用() – KF2 2013-04-10 17:54:19