2013-03-04 100 views
0

我想要顯示一個循環的內容到我的用戶界面。首先,我不知道我這個接近(使用的WinForms)正確的做法,但這是我在做什麼:跨線程錯誤,儘管設置ApartmentState

foreach (string item in stringArray) 
{ 
     Thread thread = new Thread(delegate() 
           { 
            UpdatedResultEvent(item); 
           }); 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 
} 

我希望這是足夠的信息,但如果不是,那麼我會在這裏詳細介紹一下。

我有2個類,我的Program.cs(WinForm)和另一個類叫做logicClass。我將我的Program對象的一個​​實例傳遞給我的logicClass。我的logicClass有一個簽名與我的Program類中的方法相匹配的委託。這是作爲一個代表通過該方法是

public void UpdateResultsOnScreen(string newContent) 
{ 
txtResults.Text += newContent; 
} 

該錯誤消息是

跨線程操作無效:控制從一個線程 比它是在

創建的線程以外訪問

編輯

的目標是,類似的方式ŧ他進度條的作品,就是看到Control實時更新。目前,即使它確實起作用,線程也不會將「結果」返回到屏幕,直到線程完成。

回答

1

使用它(如果你是的WinForms):

public void UpdateResultsOnScreen(string newContent) 
{ 
    txtResults.BeginInvoke(
     new Action<string>((value) => 
     { 
      txtResults.Text += value; 
     }), 
     newContent); 
} 

另外,作爲animaonline說,可以考慮使用ThreadPoolParallel.ForEach

+0

這真的很好,但它並沒有在屏幕上實時顯示我的結果。我的文本框仍然一次顯示所有內容,而不是一次填充一個項目。例如,假設每次調用UpdatedResultEvent(item)時都花費5秒(由於數據庫/ webservice調用等)。這意味着我希望我的屏幕更新5秒。 – Dave 2013-03-04 10:10:03

+0

@DaveRook嘗試我編輯的代碼。我認爲即使是舊的代碼('Invoke')也應該按照你的期望工作和更新UI,但是如果它不起作用,我們需要知道你是如何準確地完成它的。我認爲這應該是另一個問題。 – 2013-03-04 10:20:34

+0

是的,我已經嘗試了使用BeginInvoke(),但結果相同。如果你認爲這應該起作用,那麼也許在我的設計中哪裏是錯的! – Dave 2013-03-04 10:28:15

1

即使您正在設置ApartmentState,也必須在從另一個(非UI)線程訪問時調用UI控件。

確保在UpdateResultEvent方法中調用UI控件。

不管怎麼說,你在做什麼是不是一個好主意,考慮使用ThreadPoolParallel.ForEach

它會自動調整你的代碼,產卵一堆線程才能真正降低性能,特別是如果你有收藏很多物品在裏面。

0

這樣做怎麼樣?

public void UpdateResultsOnScreen(string newContent) 
    { 
     if(txtResults.InvokeRequired) 
     { 
      txtResults.Invoke(
       new Action<string>(content => txtResults.Text += content), newContent); 
      return; 
     } 
     txtResults.Text += newContent; 
    } 
相關問題