假设我有一个诸如ThreadPool.QueueTask(Delegate d)之类的方法。

这些委托(delegate)中的一些需要返回值,但是由于它们不能做到这一点(作为委托(delegate)传递),因此需要通过引用将值作为参数。任务完成后,此值将被更改,因此调用方法需要知道这一点。

本质上,将任务传递给线程池的方法应等待完成。

做这个的最好方式是什么?我应该只是执行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的使用毫无意义。

或者,您可能要使用单独的委托(delegate)作为回调:
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):
您甚至可能不需要回调委托(delegate),您可以直接调用OnTaskComplete,这也可以完成这项工作:
public void TaskStartMethod()
{
    ThradPool.QueueUserWorkItem(o=>
    {
        // Perform the task

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

10-08 16:15