2009-09-04 8 views
0

今日私はWCFの質問をしていますが、おそらく.NETの他のネットワークモデルも関係しています。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で取得するコールバックチャネルで呼び出されます。

DuplexSessionChannelのクライアントは、サービスコールバックチャネルからメッセージを受信するときにBeginReceive()/ EndReceive()を呼び出します。

実際には機能していますが、End <Operation>()メソッドが実際に何をしているのか分かりませんが、これが私に説明しておく必要があります。

コレクションが変更されていると不平を言って、サービス上のEndSend()の呼び出しで時折例外が発生するため、私は尋ねます(この例外の意味は分かりますが、起こっているか、まさに...)。私はSilverlightクライアントでPollingDuplexHttpBindingを使用しています。

私はWCFのエキスパートではありませんが、詳細を保持していません。知識が必要です。これまでの私のキャリアの中で、他の非同期操作の前にこの種のBegin/Endパターンを見たことがありますが、実際に何が起こっているのかは決して理解できません。

ありがとうございます。

答えて

1

ご質問のように聞こえるのは、Begin/End APM(非同期プログラミングモデル)です。簡単に言えば、APMは

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

などの同期方法をとり、非同期BeginFooとEndFooメソッドにそれを破ります。主な利点は、動作が長期間(例えば他の機能と比較して、例えばネットワークとの通話に数百ミリ秒以上かかることがある)真の非同期システム動作(例えば、ネットワークとの通話)を行っているときである。このパターンを使用すると、システムに操作を開始するように指示し、操作の結果が準備完了になったときにコールバックすることができます。パターンの利点は、この呼び出しが保留されている間にマネージスレッドをブロックする必要がないことです(何千ものスレッドを必要とせずに何千もの保留中のネットワーク読み取り/書き込みが可能で、スレッドが高価です)。

「BeginFoo」は、「これらの引数を使ってメソッドを開始する」ということです。その後、(結果が準備完了であるという通知として)コールバックされると、「EndFoo」は結果を取得する方法です。一般的なケースでは、 'Foo'が特定の例外をスローする可能性がある場合、この例外は 'Begin'コールまたは 'End'コールのいずれかから出てくる可能性があり、両方の場所でそれを処理する準備が必要です。

Send()(空白を返すかもしれませんか?忘れてしまいます)のようなものの場合は、ちょっと邪魔になります。ただし、例外が発生する可能性があります(たとえば、送信しようとしましたが、ネットワークケーブルを抜いた人など)。これにより例外が発生する可能性があります。開始/終了APMを指定すると、EndSend呼び出しから例外が発生する可能性があります。実際には、例外はSendを呼び出すときの「結果」の一種であるため、EndSendを呼び出すと、BeginSendを呼び出した後に何か問題が発生したという例外がスローされます。 WCF IDuplexSessionChannel.BeginSendとEndSendにおいて

+0

は、次のシグネチャがあります。 たIAsyncResult BeginSend(メッセージ、AsyncCallback、オブジェクト) 空隙EndSend(たIAsyncResult)。 BeginSendに渡されたAsyncCallbackデリゲートによって呼び出されるコールバックメソッドの内部からEndSendを呼び出します。 EndSend()がvoidを返すことを考えれば、私はそれが何のためであるかまだ分かりません。私が見ている "結果"は、BeginSends AsyncCallbackから来ています。またBeginSend AsyncCallbackによって非同期的に返される場合、なぜBeginSendがIAsyncResultを返すのか理解できません。 – MrLane

+0

この質問を投稿してから数ヶ月後にBriansの投稿を読んでください。 Juval LoweryのプログラミングWCFの本でも同様にこのことが説明されています。私はまだ例外の原因を知っていませんが、私はもはや結果が返されていないことを認識しているので、もはやEndSend()を呼び出さなくなってしまっています。私はこれが良い習慣であるかどうかは分かりません(おそらく私は例外の詳細を見逃す可能性があります)が、この本は省略可能であることを示唆しているようです。 – MrLane

関連する問題