2009-09-04 2 views
0

오늘 .NET의 다른 네트워킹 모델과 관련되어 있지만 WCF 질문이 있습니다.WCF : DuplexSessionChannel, 비동기 작업 및 예외

OneWay = true 인 Send (Message) OperationContract를 노출하는 WCF 서비스가 있습니다. 이제이 서비스에는 클라이언트에게 메시지를 반환하는 콜백 채널이 있습니다.

어쨌든 (성공적으로) 내 클라이언트에서이 Send 메서드를 비동기 적으로 호출하려고합니다. DuplexSessionChannel에서 BeginSend (Message, OnSendComplete, null)를 호출하고 있고 DuplexSessionChannel에서 EndSend (asyncResult)를 호출하는 OnSendComplete (IAsyncResult) 메서드가 있습니다.

서비스에는 CallbackContract가 있으며 클라이언트에 다시 전송하기 위해 동일한 BeginSend()/EndSend() 패턴이 사용됩니다.이 패턴은 OperationContext.Current.GetCallbackChannel에서 얻은 callBack 채널에서 호출됩니다.

DuplexSessionChannel의 클라이언트는 서비스 콜백 채널에서 메시지를받을 때 BeginReceive()/EndReceive()를 호출합니다.

일들이 실제로 작동하더라도 실제로 <Operation> (끝) 메서드가 수행하는 내용을 이해하지 못하고 이것이 나에게 설명해야 할 내용입니다.

콜렉션이 수정되었음을 불평하는 서비스 (클라이언트에게 다시 보내기)에 대한 EndSend() 호출에서 가끔 예외가 발생하므로 요청합니다. (이 예외의 의미는 무엇인지는 알지만 왜 그런지는 알지 못합니다. 일어나는 곳 또는 정확히 ...). Silverlight 클라이언트에서 PollingDuplexHttpBinding을 사용하고 있습니다.

저는 WCF 전문가가 아니지만 세부 정보를 갖고 있지는 않습니다. 지식이 필요합니다. 지금까지 필자는 다른 비동기 작업을 시작하기 전에 이러한 종류의 Begin/End 패턴을 보았지만 실제로 어떤 일이 벌어지고 있는지 전혀 이해하지 못했습니다.

미리 감사드립니다.

답변

1

질문과 같이 들리 겠지만 시작/종료 APM (비동기 프로그래밍 모델)에 관한 것입니다. 간략하게, APM은

R Foo(A a); // R is some result type, A is some argument type 

같은 동기 방식과 비동기 얻어 BeginFoo 및 EndFoo 방법으로 나누기. 주된 이점은 동작이 장기 실행 일 수있는 (예를 들어 네트워크와의 통신이 수백 밀리 초 또는 그 이상 걸리는 등의 다른 기능과 비교하여) 진정한 비동기 시스템 동작 (예를 들어, 네트워크과의 통신)을 수행 할 때 발생한다. 이 패턴을 사용하면 시스템에 작업을 시작하도록 지시 한 다음 작업 결과가 준비되면 다시 호출 할 수 있습니다. 패턴의 이점은이 호출이 보류 중일 때 관리되는 스레드를 차단할 필요가 없다는 것입니다. 즉, 수천 개의 스레드, 만세, 스레드가 비싸지 않으면 서 수천 개의 보류중인 네트워크 읽기/쓰기를 가질 수 있습니다.

'BeginFoo'는 '이 인수로 메소드 시작'이라고 말한 다음 결과가 준비되었다는 알림으로 다시 호출 될 때 'EndFoo'는 결과를 얻는 방법입니다 . 일반적인 경우, 'Foo'가 특정 예외를 throw 할 수있는 경우이 예외는 'Begin'호출 또는 'End'호출에서 나올 수 있으므로 두 위치 모두에서이 예외를 처리 할 준비가되어 있어야합니다.

Send()와 같은 경우 (아마도 무효를 반환하겠습니까?) 잊어 버립니다. 일방성이므로 '불과 잊기'를 원하기 때문에 조금 성가거나 이상합니다. 하지만 예외가 계속 발생할 수 있습니다 (예 : 전송하려했지만 다른 사람이 네트워크 케이블을 분리 함). 따라서 예외가 발생할 수 있습니다. 시작/종료 APM이 주어지면 이러한 예외가 EndSend 호출에서 나올 수 있습니다.사실, 예외는 Send를 호출하는 것과 같은 일종의 '결과'이기 때문에 EndSend를 호출하면 BeginSend를 호출 한 후 문제가 발생했다는 예외를 throw 할 수있는 방법이 제공됩니다.

+0

IDuplexSessionChannel.BeginSend 및 EndSend에는 다음과 같은 서명이 있습니다. IAsyncResult BeginSend (Message, AsyncCallback, object) void EndSend (IAsyncResult); BeginSend에 전달 된 AsyncCallback 대리자에 의해 호출되는 콜백 메서드 내부에서 EndSend를 호출합니다. EndSend()가 void를 반환한다고 가정 할 때, 나는 그것이 무엇인지 이해하지 못한다. "결과"는 BeginSend AsyncCallback에서 볼 수 있습니다. 또한 BeginSend AsyncCallback에 의해 비동기 적으로 반환 될 때 BeginSend가 IAsyncResult를 반환하는 이유를 이해하지 못합니다. – MrLane

+0

Brians가 내가이 질문을 게시 한 후 몇 달 후에 다시 읽으면이 패턴으로 훨씬 더 명확 해집니다. Juval Lowery가 프로그래밍 한 WCF 책은 이것을 잘 설명합니다. 나는 여전히 예외의 원인을 모르고 있지만 EndAnd()를 더 이상 호출하지 않아 제거되었습니다. 어쨌든 결과는 반환되지 않습니다. 이것이 좋은 연습인지 (아마도 예외적 인 세부 사항이 누락 될 수는 있겠는가) 모르겠다. 그러나이 책은 생략 될 수 있다고 제안하는 것처럼 보이고 제거하는 것이 훨씬 더 효과적이기 때문이다. – MrLane