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

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

vsDelegate.BeginInvoke 대 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쪽으로 기울어졌습니다. 그러나 실제로 더 좋은 것은 아니지만,이 경우에도 일반적으로 더 좋은 것은 아닙니다.

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

+0

Framework 4.0을 사용 중입니다. 확장 할 수 있습니까? 아마도 답변으로 게시 할 수 있습니까? – bevacqua

답변

2

비동기 대표는 반환 값과 예외 전달 (EndInvoke를 호출하여 액세스 권한을 얻어야 함)을 제공합니다. ThreadPool을 직접 사용하면 직접 처리해야합니다.

반면에 ThreadPool의 장점은 단순합니다.

두 가지 이상의 방법을 깊이있게 다루는이 우수 온라인 book을 살펴보십시오.엄지 손가락의 규칙으로

:

  • 사용 TPL 만약 당신이 할 수있는
  • 대표 비동기 사용하지 않을 경우
  • 작업을 파이어 앤 포겟 직접 간단한위한 ThreadPool이를 사용하지 않을 경우
+0

TPL을 확장 할 수 있습니까? 어쩌면 링크일까요? – bevacqua

+0

물론입니다. 위의 책은 병렬 프로그래밍에 대한 장을 가지고 있습니다 : http://www.albahari.com/threading/part5.aspx, 위키 피 디아도보십시오 : http://en.wikipedia.org/wiki/Task_Parallel_Library#Task_Parallel_Library – grzeg

+0

QueueWorkerUserItem의 장점은 응답을 기다릴 필요가 없으므로 BeginInvoke가 EndInvoke를 따라야한다는 것입니다. 그렇지 않으면 메모리가 누출됩니다. – Jaap

1

ThreadPool.QueueWorkerUserItem이 더 높고 바람직하다. 그러나 장면 뒤의 ThreadPool.QueueWorkerUserItemDelegate.BeginInvoke을 사용합니다. Delegate.BeginInvokeThreadPool의 스레드를 사용합니다.

3

또한 Delegate.BeginInvoke() 메서드는 ThreadPool을 사용하므로 성능에 의미있는 차이가 없어야합니다.

QueueUserWorkItem()은 더 나은 것은 아니지만 대부분의 경우 더 쉽습니다.

그러나 두 샘플 모두 오류 처리가 없습니다.
좋은 짧은 대리인은 try/catch가 필요하며 BeginInvoke 시나리오는 콜백이 필요합니다.

그래서 Fx4를 사용할 수있는 경우 훨씬 높은 추상화 수준으로 TPL을 사용해야합니다.

+2

[이 게시물] (http://shevaspace.blogspot.com/2007/08/delegatebegininvoke-vs.html)은 BeginInvoke와 QueueUserWorkItem 사이의 중요한 차이점을 보여줍니다. – Gqqnbig