2011-01-21 16 views
2

假設我有一個方法,比如ThreadPool.QueueTask(Delegate d)。我寫了一個線程池,如何通知使用它的方法,任務已完成?

其中一些代表需要返回值,但由於他們無法做到這一點(作爲委託傳遞),他們將需要通過引用將值作爲參數。一旦任務完成,這個值將被改變,所以調用方法需要知道這一點。

實質上,將任務傳遞給線程池的方法應該等待,直到它完成。

這樣做的最好方法是什麼?我應該只是做Threadpool.QueueTask(Delegate d,EventWaitHandle e),還是有一種更優雅的方式,對於那些不熟悉這種事情的人來說顯而易見?

親切的問候, 府谷

+1

是否有任何理由不能使用TPL來做到這一點?如果這對您有用,我可以提出一個好的解決方案。 – 2011-01-21 15:51:32

+0

什麼是TPL? – Fugu 2011-01-21 15:55:11

回答

5

您可以使用ManualResetEvent

public void TaskStartMethod() 
{ 
    ManualResetEvent waitHandle = new ManualResetEvent(false); 

    ThreadPool.QueueUserWorkItem(o=> 
    { 
     // Perform the task here 

     // Signal when done 
     waitHandle.Signal(); 
    }); 

    // Wait until the task is complete 
    waitHandle.WaitOne(); 
} 

從本質上講,傳遞 任務線程池的方法應該是 等待,直到它完成。

上面的代碼是這樣做的,但現在我有一個問題:如果您的方法正在等待任務完成,那麼爲什麼你甚至懶得在單獨的線程上執行任務?換句話說,你所描述的是代碼的順序執行而不是並行執行,所以使用ThradPool是毫無意義的。

或者,你可能可能需要使用一個單獨的委託作爲回調:

public delegate void OnTaskCompleteDelegate(Result someResult); 

public void TaskStartMethod() 
{ 
    OnTaskCompleteDelegate callback = new OnTaskCompleteDelegate(OnTaskComplete); 
    ThradPool.QueueUserWorkItem(o=> 
    { 
     // Perform the task 

     // Use the callback to notify that the 
     // task is complete. You can send a result 
     // or whatever you find necessary. 
     callback(new Result(...)); 
    }); 

} 

public void OnTaskComplete(Result someResult) 
{ 
    // Process the result 
} 

更新(2011/1/24): 你可能甚至不需要回調委託,你可以直接調用OnTaskComplete和應該做的工作太多:

public void TaskStartMethod() 
{ 
    ThradPool.QueueUserWorkItem(o=> 
    { 
     // Perform the task 

     // Call the method when the task is complete 
     OnTaskComplete(new Result(...)); 
    }); 
} 
1

取決於你是如何做的。對我來說,聽起來有點像你有線程A把一個任務放到線程池中,然後等待它完成。這聽起來不是很有幫助。如果你在線程池中放置一個任務並等待,只需在你自己的線程中完成。

但這可能不是你在做什麼!

我可以看到使用線程池的兩種可能的好方法。線程A有多件事情要並行啓動,然後等待它們全部完成。在這種情況下,您需要爲所有任務(或結果類)存儲句柄,因此您可以等待它們全部完成。你可以使用semiphores或各種同步工具(我不專門做c#)以避免忙於輪詢。

另一種方法是在任務結束時使用回調。線程A啓動線程池上的任務,然後存在。任務有一個返回給它的類的句柄,當它完成時調用一個回調類型函數來完成最終化類型的東西。

相關問題