1

クライアントがクライアント UI から WCF サービス ホストへの非同期プロセスを呼び出し、クライアントにプロセスの状態を通知する方法を探しています。これは、saga (プロセス マネージャー)、ドメイン イベント、および WCF 二重接続で実現できると思いますが、その方法はわかりません。

ケースシーケンス(推測)は次のようになります。

  1. クライアントがプロセスを呼び出す
  2. クライアントが WCF プロキシを作成する
  3. プロキシはサービス ホストに接続します
  4. サービス ホストがクライアントへの二重チャネルを作成する
  5. サービス ホストは、コマンド バスを使用してプロセスを開始し、二重チャネルを渡します
  6. プロセス状態変化!
  7. 関連するデュプレックス チャネルを見つける
  8. プッシュ バック ステータス変更
  9. クライアントはステータスの変更を受け取り、視覚化します

私はこれで正しいですか?要するに、関連するクラスはどのように見えるでしょうか? はい、私は NServiceBus を認識しています (そのような場合によく言及されます) が、追加のフレームワークに依存したくありません (NServiceBus が自分で解決できることはすでにたくさんあり、すでに数百を使用しています)あらゆる種類のもののための異なるフレームワークの..)

編集: これは、私の質問を特定する可能性のある実際の例です。

画像を使って魔法やユニコーンのような処理を行う画像処理サーバーがあります。WCF クライアントは画像をサーバーにアップロードし、処理された画像の量を示す進行状況バーを表示します。サーバーは新しい ImageProcessService を (リクエスト スコープで) 開始します。処理中に、プロセスをパーセントで示す数字とともに多数の ImageProcessStateChanged イベントをスローする可能性があります。完了したら、ImDoneEvent をスローする可能性があります。すべてのイベントは、適切なクライアントに信号を返すイベント バスによってキャッチされる必要があります。このプロセスには最大 60 秒かかる場合があり、クライアントごとに 1 回起動できますが、できるだけ多くのクライアントに対して起動できます。

4

2 に答える 2

4

探しているのは、操作コントラクトで IsOneWay=true を設定することで有効になる動作だけのようです。操作コントラクトで IsOneWay=true を設定すると、呼び出し元は要求を送信しますが、応答を待ちません。応答を取得するには、呼び出し先は、IsOneWay=true が設定されている二重チャネルのコールバック チャネルで別の操作を呼び出す必要があります。

必要最小限の例を次に示します。

サービス契約:

[ServiceContract( CallbackContract = typeof( IClientCallback ), SessionMode = SessionMode.Required )]
public interface IClientService
{
    [OperationContract( IsInitiating = true )]
    void CreateSession( string windowsUserName );
    [OperationContract( IsOneWay = true )]
    void LongOp( );
    [OperationContract( IsTerminating = true )]
    void Terminate( );
}

クライアント コールバック コントラクト:

[ServiceContract]
public interface IClientCallback
{
    [OperationContract( IsOneWay = true )]
    void LongOpResponse( );
}

サービスの実装:

class ServerService : IClientService
{
    public void CreateSession( string windowsUserName )
    {
        //Do stuff to set up your session as desired
    }

    public void LongOp( )
    {
        //Do something that takes a long time
        LongRunningFunctionCall();
        Callback.LongOpResponse();
    }

    public void Terminate( )
    {
        //Do stuff to tear down your session
    }

    public IClientCallback Callback { get { return OperationContext.Current.GetCallbackChannel<IClientCallback>( ); } }
}

クライアント コールバックの実装:

class CallbackHandler : IClientCallback
{
    public void LongOpResponse( )
    {
        Console.WriteLine( "Received long operation response from server." );
    }
}

各セッションを処理しているクライアント サービス オブジェクトへの参照がある限り、そのオブジェクトを介してそのコールバック チャネルに直接アクセスできます。チャネルが開いています。

通常、二重チャネルのサービス コントラクトでは、IsOneWay=false を使用した操作よりもはるかに多くの一方向の操作が行われます。ただし、呼び出し元のアプリケーションの継続に即時の応答が不可欠な操作は除きます。

于 2014-06-05T18:06:47.943 に答える
0

これは、Task Parallelism または IAsyncResult を使用して実現できます。

IAsyncResult はその AsyncWaitHandle に WaitOne を持っているため、クライアントはそれが非同期で実行を終了するのを待ってから、非同期メソッドの End 呼び出しを呼び出して値を取得できます。

例になります。

public IAsyncResult Process(type param, AsyncCallback callback, object state)
{
   // code here to process
}

public TypeResult EndProcess(IAsyncResult ar)
{
   // return result here
}

これで、コールバックを使用してクライアントからメソッドを呼び出すことができます。この場合、状態について通知するために使用できます。

IAsyncResult の詳細:こちら

于 2014-06-02T06:35:21.160 に答える