2011-04-19 50 views
6
public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     var replyCopy = reply; 

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

VSDelegate.BeginInvoke VS ThreadPool.QueueWorkerUserItem

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倾斜的我不知道哪一个是真正好,无论是在这种情况下,也不在一般

UPDATE

我了解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方法中可能出现的异常吗?

+1

您正在使用哪个版本的.NET?如果你使用.NET 4,你应该使用Task Parallel Library。那么,不是'应该',而是'强烈鼓励'。 – Tejs 2011-04-19 20:55:52

+0

我正在使用框架4.0,你可以展开,也许发布它作为答案? – bevacqua 2011-04-19 22:25:06

回答

2

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

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

看看这个优秀的在线book,它讨论了深入的两个(和更多)方法。

作为一个经验法则:

  • 使用TPL,如果你能
  • 如果不使用线程池直接进行简单的发射后不管任务
  • 如果不是异步委托使用
+0

您可以扩展TPL吗?一个链接可能? – bevacqua 2011-04-20 11:12:43

+0

当然。上面这本书有关于并行编程的一章:http://www.albahari.com/threading/part5.aspx,看一下wikipedia:http://en.wikipedia.org/wiki/Task_Parallel_Library#Task_Parallel_Library – grzeg 2011-04-20 14:14:12

+0

QueueWorkerUserItem的优点是你不必等待答案,最终BeginInvoke必须跟着一个EndInvoke,否则你就是在泄漏内存。 – Jaap 2013-04-26 15:43:33

1

ThreadPool.QueueWorkerUserItem是较高水平并且是优选的。 但是ThreadPool.QueueWorkerUserItem幕后使用的是Delegate.BeginInvokeDelegate.BeginInvoke使用ThreadPool的线程。

3

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

QueueUserWorkItem()不是直接更好,只是在大多数情况下更容易。

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

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

+2

[这篇文章](http://shevaspace.blogspot.com/2007/08/delegatebegininvoke-vs.html)揭示了BeginInvoke和QueueUserWorkItem之间的重要区别。 – Gqqnbig 2012-07-25 02:58:25

相关问题