2010-10-12 28 views
0

我正在嘗試多線程,但我無法弄清楚爲什麼在調用task.Execute()時,下面的代碼塊會阻塞UI?使用BeginInvoke在後臺線程上執行

public class Task<TRes> 
{ 
    private Func<TRes> _func; 
    public Task(Func<TRes> func) 
    { 
     _func = func; 
    } 
    public TRes Execute() 
    { 
     var iasync = _func.BeginInvoke(null, null); 
     return _func.EndInvoke(iasync); 
    } 
} 

我不想特別解決任何問題。只是想知道爲什麼即使當前線程(放置到「睡眠」的那個線程是ThreadPool線程(而不是主UI線程))時它阻塞Thread.Sleep。以下是使用Task類的按鈕單擊事件。

var task = new Task<string>(() => 
      { 
       var start = DateTime.Now; 
       var isBackGround = Thread.CurrentThread.IsBackground ; 
       var isThreadPool = Thread.CurrentThread.IsBackground; 

       Thread.Sleep(5000); 
       return String.Format("Start {0} : End {1}", start, DateTime.Now); 
      } 
     ); 
     this.label1.Text = task.Execute(); 

回答

1

問題是調用EndInvoke會阻止調用線程,直到該函數完成執行。你正在做的是產生一個工作者線程來執行你的_func,然後阻塞,直到該工人完成。我會建議使用BeginInvoke的回調參數。如果你在做圖形用戶界面的話,不要忘記Dispatcher

想一想,我不會推薦用GUI開始多線程,因爲它可能是一個真正的痛苦。從控制檯應用程序開始,讓您可以掌握整個多線程的東西,然後轉到GUI,在那裏可能會變得很痛苦。

void Main() 
{ 
    var cookies = new IAsyncResult[10]; 
    Action action = delegate 
    { 
     // I'm going to print out a bunch of numbers here 
     for (int i = 0; i < 100; ++i) 
      Console.WriteLine(i); 
    } 

    for (int i = 0; i < cookies.Length; ++i) 
     cookies[i] = action.BeginInvoke(null, null); 

    // with all 10 threads executing, you'll see numbers print out in some crazy, 
    // unpredictable order...this line will come out somewhere in the mess (or maybe 
    // before it...who knows?) 
    Console.WriteLine("All threads started!"); 

    // we wait for each of the workers to finish executing here: 
    foreach (var c in cookies) 
     action.EndInvoke(c); 

    // and this will always be printed last, thereby demonstrating that EndInvoke 
    // causes the calling thread to wait for the action to finish 
    Console.WriteLine("Done!"); 
} 
0

我知道這個開不直接回答你的問題,但我只是想爲您指出在System.Threading.Tasks命名空間,如果你使用的是.NET 4.0。 T(T)的任務確實有很好的文檔記錄,並按預期執行。

-Josh

相關問題