2011-04-19 26 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

相關問題