Delegate.BeginInvoke vs ThreadPool.QueueWorkerUserItem

时间:2011-04-19 20:52:34

标签: c# wpf multithreading performance asynchronous

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var replyCopy = reply;

        ThreadPool.QueueUserWorkItem(delegate
        {
            RequestQueueHandler.RequestQueue.Add((Message)correlationState, replyCopy);
        });
    }

VS

    private delegate void RequestQueueHandlerAdd(Message request, Message reply);

    private static void AsyncMethod(Message request, Message reply)
    {
        RequestQueueHandler.RequestQueue.Add(request, reply);
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        ((RequestQueueHandlerAdd)AsyncMethod).BeginInvoke((Message)correlationState, reply, null, null);
    }

我应该使用这两个中的哪一个? (表现更好?) 为什么呢?
我的方法的开销是否会影响决策,或者其中一个实现总是优于另一个? 是什么原因?

我倾向于使用ThreadPool.QueueWorkerUserItem,但我不知道哪一个实际上更好,在这种情况下也不是一般的

更新

我读了一些关于TPL的东西......解决了这个问题:

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var replyCopy = reply;
        var enqueue = Task.Factory.StartNew(() => RequestQueueHandler.RequestQueue.Add((Message)correlationState, replyCopy));

    }

我该怎么办这个例外?我的意思是,如果我做的话

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var replyCopy = reply;
        var enqueue = Task.Factory.StartNew(() => RequestQueueHandler.RequestQueue.Add((Message) correlationState, replyCopy));

        **try
        {
            enqueue.Wait();
        }
        catch(AggregateException e)
        {
            Handle(e);
        }**
    }

我是不是错过了这里的平行点?

我不应该只处理RequestQueueHandler.RequestQueue.Add方法中可能的异常抛出吗?

3 个答案:

答案 0 :(得分:3)

Delegate.BeginInvoke()方法也使用ThreadPool,因此不要指望性能有任何有意义的差异。

QueueUserWorkItem()并非直接更好,在大多数情况下更容易。

但请注意,两个样本都缺少错误处理 你的短代表需要一个try / catch,BeginInvoke场景需要一个回调。

因此,当你可以使用Fx4时,你应该使用TPL来获得更高的抽象级别。

答案 1 :(得分:2)

异步委托给你更多:返回值和异常转发(你应该调用EndInvoke来访问它们)。 通过直接使用ThreadPool,您必须自己处理。

另一方面,ThreadPool的优点是简单。

请看一下这个优秀的在线book,它深入讨论了两种(以及更多)方法。

作为一个拇指规则:

  • 如果可以,请使用TPL
  • 如果不直接使用ThreadPool进行简单的即发即弃任务
  • 如果不使用异步委托

答案 2 :(得分:1)

ThreadPool.QueueWorkerUserItem是更高级别的首选。 但幕后的ThreadPool.QueueWorkerUserItem使用Delegate.BeginInvokeDelegate.BeginInvoke使用ThreadPool中的线程。