![](/img/trans.png)
[英]How do I fix the deadlock on a threadpool thread that has a SynchronizationContext?
[英]I've written a threadpool, how do I notify methods using it that the task has been completed?
假设我有一个诸如ThreadPool.QueueTask(Delegate d)之类的方法。
这些委托中的一些需要返回值,但是由于它们不能做到这一点(作为委托传递),因此需要通过引用将值作为参数。 任务完成后,此值将被更改,因此调用方法需要知道这一点。
本质上,将任务传递给线程池的方法应等待完成。
做这个的最好方式是什么? 我应该只是执行Threadpool.QueueTask(Delegate d,EventWaitHandle e),还是有一种更优雅的方式,这种方式对于不熟悉这种事情的人来说是显而易见的?
亲切的问候
您可以使用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(...));
});
}
取决于您的操作方式。 对我来说,听起来有点像线程A将单个任务放在线程池上,然后等待该任务完成。 听起来不是很有帮助。 如果要将一项任务放在线程池上并等待,只需在自己的线程中执行即可。
但这可能不是您的工作!
我可以看到使用线程池的两种可能的好方法。 线程A有多个要并行启动的事物,然后等待它们全部完成。 在这种情况下,您需要存储所有任务(或结果类)的句柄,以便可以等待它们全部完成。 您可以使用符号或各种同步工具(我不专门使用c#)来避免忙于轮询。
另一种方法是在任务结束时使用回调。 线程A在线程池上启动任务,然后存在。 该任务具有返回到开始该类的类的句柄,并在完成后执行回调类型函数来调用回调类型函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.