2011-11-23 20 views
1

時延我有這個代碼在C#中的一個問題:多線程在WinApp構成C#

main class { 
var trick = new Object(); 
} 
....... 
public void AddTabWithCheck(List<Urls> url) 
{ 

//Some Code 

foreach(Urls link in url){ 
    var thread = new System.Threading.Thread(p => 
     { 
      lock (trick) 
      { 
       Action action =() => 
       { 
        addTab(link); 
       }; 
       this.Invoke(action); 
       if(link.Host == "google") 
        System.Threading.Thread.Sleep(5000); 
      } 
     }); 
     thread.Start(); } 
} 

我有問題winapp形式做一個時間延遲。

我coudnt使用線程睡眠,while(withDatetime)或類似becouse內WinAPP有一個WebControl瀏覽器,我希望在一些延遲時間的循環中添加一些頁面,而不凍結用戶界面。這兩個計時器都不是一個好的解決方案,因爲我的情況很難處理。

所以一個用戶建議我使用這個解決方案(帶Thread的)。 我以爲它的工作沒有問題,但只有現在我意識到,如果我把我的循環只取最後一個元素(的循環),並創建X線程都具有相同的元素。

爲了更好地解釋:我有這個List<Urls> url ;

與此類

public class Urls { 
      public string Host { get; set; } 
      public String url { get; set; } 
} 

現在我無法理解爲什麼如果我添加一個簡單的foreach內部的代碼,當線程開始全部使用循環的最後一個元素。

我已經檢查過列表是否正確,在線程代碼之前添加一個MessageBox來顯示當前對象,並且它正確地更改。

回答

2

所有匿名方法都共享相同的link變量。

您需要在循環中聲明一個單獨的變量,以便每個方法都有自己的變量。

+0

我剛剛嘗試創建Url tmp = new Urls(); (在循環之前)然後在循環內部tmp = link;我用tmp代替鏈接,但它是一樣的。我希望這就是你的意思:) – Jasper

+0

@Jasper:你的foreach中的第一行需要這個:'var linkCopy = link;'然後你使用'linkCopy'而不是'link'。 –

+0

@Jasper No,'Urls tmp = link;'應該在循環中聲明並設置。 [這是爲什麼。](http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx) –