2011-06-17 48 views
0

起初我有線程等待的例子,它的工作原理是完美的。它的任務是要求100個線程等待3秒鐘,然後使輸出:找不到並行的異步調用(多線程)

for (int i = 0; i < 100; ++i) 
{ 
    int index = i; 
    Thread t = new Thread(() => 
     { 
      Caller c = new Caller(); 
      c.DoWaitCall(); 
     }) { IsBackground = true }; 
    t.Start(); 
} 

來電:: DoWaitCall()看起來像:

public void DoWaitCall() 
{ 
    Thread.Sleep(3000); 
    Console.WriteLine("done"); 
} 

在這種情況下,所有的線程等待3秒鐘,並給輸出消息幾乎在同一時間。

但是,當我嘗試使用異步回調做Console.WriteLine命令:

public void DoWaitCall() 
    { 
     MyDel del =() => { Thread.Sleep(3000); }; 
     del.BeginInvoke(CallBack, del); 
    } 

    private void CallBack(IAsyncResult r) 
    { 
     Console.WriteLine("done"); 
    } 

每個線程等待不同的時間,並使它們的輸出一個接一個緩慢。 有沒有什麼好的方法可以並行實現異步回調?

回答

2

你看到的效果是ThreadPool逐漸增加,基本上。這個想法是創建(然後保持)線程相對昂貴,並且ThreadPool專爲短期運行任務而設計。因此,如果它在很短的時間內收到一堆任務,那麼對它們進行批處理是有意義的,只有在發現仍有任務稍後等待時纔開始新線程。

你可以強制它使用ThreadPool.SetMinThreads來保持最少的線程數。對於real系統,您通常不需要這樣做,但對於演示或類似的東西來說它是有意義的。

1

您第一次產生了許多並行執行作業的線程。第二次使用線程池的線程數量有限。正如喬恩指出的,你可以使用一個屬性來定義最小線程數。

但是,爲什麼你需要從並行線程進行異步調用?
這完全不會改善您的性能,因爲您的工作已經並行完成,並且您正在進行另一次拆分(使用線程池),由於線程上下文切換,這將引入更多的延遲。沒有必要這樣做。

+0

因爲沒有可用的等待版本,所以我使用異步。那麼爲什麼我的等待(非異步)程序運行良好而不設置threadPool minThreads? – demaxSH 2011-06-17 06:54:35

+0

@demaxSH由於您手動創建100個線程,因此不使用該池。當你使用異步調用時,它在線程池中完成,線程池的線程數量有限(由MaxPoolThread定義)。所以最初你有100個線程,然後你分裂到另一個* N *線程,並等待直到* N *線程完成。 – oleksii 2011-06-17 07:03:06