所以我想说我有一个方法,比如ThreadPool.QueueTask(Delegate d)。
其中一些委托需要返回值,但由于它们无法执行此操作(作为委托传递),因此需要通过引用将值作为参数。任务完成后,该值将被更改,因此调用方法需要知道这一点。
基本上,将任务传递给线程池的方法应该等到它完成。
最好的方法是什么?我应该只做Threadpool.QueueTask(Delegate d,EventWaitHandle e),还是有一种更优雅的方式对于那些不熟悉这种事情的人来说是显而易见的?
亲切的问候, 河豚
答案 0 :(得分: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
}
更新(1/24/2011):
您可能甚至不需要回调代理,您可以直接调用OnTaskComplete
,这也应该完成工作:
public void TaskStartMethod()
{
ThradPool.QueueUserWorkItem(o=>
{
// Perform the task
// Call the method when the task is complete
OnTaskComplete(new Result(...));
});
}
答案 1 :(得分:1)
取决于你是如何做到的。对我来说,这听起来有点像你有线程A在线程池上放置一个任务,然后等待它完成。这听起来不是很有帮助。如果您将一个任务放在线程池上并等待,只需在您自己的线程中执行。
但那可能不是你的所作所为!
我可以看到两种可能的好方法来使用线程池。线程A有多个要并行启动的东西,然后等待它们全部完成。在这种情况下,您需要存储所有任务(或结果类)的句柄,因此您可以等待它们全部完成。你可以使用semiphores或各种同步工具(我没有特别做c#),以避免繁忙的民意调查。
另一种方法是在任务结束时使用回调。线程A启动线程池上的任务,然后存在。该任务有一个回到该类的句柄,并在完成后调用回调类型函数来完成终结类型的东西。