2010-11-14 19 views
1
private void button1_Click(object sender, EventArgs e) 
    { 
     PROGRESS_BAR.Minimum = 0; 
     PROGRESS_BAR.Maximum = 100; 
     PROGRESS_BAR.Value = 0; 

     for (int i = 0; i < 100; i++) 
     { 
      Thread t = new Thread(new ThreadStart(updateProgressBar)); 
      t.IsBackground = true; 
      t.Start(); 
     } 

    } 

    private void updateProgressBar() 
    { 
      PROGRESS_BAR.PerformStep(); 
      Thread.Sleep(4000); 
    } 

我總是得到這個錯誤: 跨線程操作無效:控制「」從比它創建的線程以外的線程訪問。無法更新螺紋加工進度條在C#

我試圖在谷歌搜索解決方案,不幸的是,他們都沒有爲我工作。有誰知道如何解決這個問題? 在此先感謝..

+0

一次製作一百個線程是一個_horrible_想法。 – SLaks 2010-11-14 23:29:38

+0

我只是測試這個。我對C#仍然很陌生。 – SolidSnake 2010-11-14 23:32:22

+0

你可能會誤解線程。您的代碼會創建一百個線程(嘗試)同時增加進度欄。在他們全部(嘗試)遞增之後,他們都會睡覺,然後退出。 – SLaks 2010-11-14 23:35:35

回答

5

不能從非UI線程的UI元素進行交互。 你需要使用如下代碼

this.BeginInvoke((Action)(() => PROGRESS_BAR.PerformStep())); 
+0

現在我得到這個錯誤:錯誤'System.Windows.Forms.ToolStripProgressBar'不包含'BeginInvoke'的定義和沒有擴展方法'BeginInvoke'接受類型'System.Windows.Forms.ToolStripProgressBar'的第一個參數可以找到(你是否缺少使用指令或程序集引用?) – SolidSnake 2010-11-14 23:33:25

+0

您可以在窗體本身上調用'BeginInvoke'。 – SLaks 2010-11-14 23:34:49

+1

對不起,只需更改PROGRESS_BAR.BeginInvoke與this.BeginInvoke – 2010-11-14 23:36:58

2

您應該使用BackgroundWorker component及其ProgressChanged事件。

可以調用DoWork處理器(運行在後臺線程)內ReportProgress方法,然後更新在ProgressChanged處理進度條(運行在UI線程)。

如果你真的想自己做(沒有BackgroundWorker的),你可以調用BeginInvoke

+0

你能展示一些代碼示例嗎? – SolidSnake 2010-11-14 23:30:41

+1

@ermac:http://msdn.microsoft.com/en-us/library/waw3xexc.aspx – SLaks 2010-11-14 23:32:01

0

你所有的UI交互,包括回調,屬性集和方法調用的,必須是在同一個線程。

其中一個回調可以啓動另一個線程(或許多線程),但它們不能直接更新UI。處理更新的方式是通過數據屬性。我的處理線程會更新進度狀態屬性。這是通過UI線程讀取的,該線程具有用於定期(100ms)更新進度條的定時器。

如果你這樣做,你需要鎖定任何用來傳遞狀態更新的對象(例如字符串)。