16

WCF サービス メソッドを呼び出すと、次のようになります。

proxy.DoSomethingAsync();
proxy.DoSomethingAsyncCompleted += OnDoSomethingAsyncCompleted;

async新しいctpを使用して同じことを行うにはどうすればよいですか? またはのようなものが必要だと思いますproxy.DoSomethingTaskAsyncproxy.DoSomethingAsync().ToTask()?Web サービス呼び出しは、キーワードTask<T>を使用できるようにするためにを返す必要がありますが、どのように??await

4

6 に答える 6

10

CTP には、通常の APM 関数 (Begin/End) を新しい async キーワードと互換性のあるものに変換する作業を行うファクトリ メソッドがあります。たとえば、次のようになります。

Stream s = new FileStream("C:\test.txt", FileMode.CreateNew);
byte []buffer = new byte[100];
int numBytesRead = await Task<int>.Factory.FromAsync(s.BeginRead, s.EndRead, buffer, 0, buffer.Length, null);

したがって、あなたの場合、同等のことを行うことができ、次のように呼び出します。

async proxy.DoSomethingTaskAsync()

詳細については、CTP ディスカッション グループのこのスレッドを参照してください

于 2010-11-04T10:31:06.397 に答える
7

async-await を使用した非同期サービスは、多くのクライアント呼び出しをインターリーブして並行して実行できるため、非常に応答性が高くなります (2)。それにもかかわらず、サービスは 1 つのスレッド (3) で完全にスレッドセーフに実行でき、セッションまたは呼び出し専用のフレームワークによって作成されたシングルトン サービス (1) またはサービス オブジェクトにすることができます。

サービスを実装するときは、 ServiceBehaviourAttributes (1)...(3) に注意してください。

    [ServiceContract( Namespace="X", Name="TheContract" )]
    public interface IAsyncContractForClientAndService
    {
        [OperationContract]
        Task<TResponse> SendReceiveAsync( TRequest req );
    }



    [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, // (1)
                      // also works with InstanceContextMode.PerSession or PerCall
                      ConcurrencyMode     = ConcurrencyMode.Multiple,   // (2)
                      UseSynchronizationContext = true)]                // (3)

    public MyService : IAsyncContractForClientAndService
    {
        public async Task<TResponse> SendReceiveAsync( TRequest req )
        {
            DoSomethingSynchronous();
            await SomethingAsynchronous(); 
            // await lets other clients call the service here or at any await in
            // subfunctions. Calls from clients execute 'interleaved'.
            return new TResponse( ... );
        }
    }

すべての呼び出しを 1 つのスレッドで実行するには、ServiceHost を Open() するときに System.Threading.SynchronizationContext.Current != null が存在する必要があります。SynchronizationContext を使用すると、ロックを気にする必要がなくなります。アトミックで割り込み不可能なコード セクションは、ある await から次の await に大まかに伸びます。共有サービスのデータが待機するたびに一貫した状態になるように注意し、1 つのクライアントからの連続する要求は、送信された順序ではなく応答される可能性があることに注意してください。

クライアント側では、非同期サービス操作が待機可能です。

   var response = await client.Channel.SendReceiveAsync( request );

操作コントラクトでoutまたはrefパラメーターを使用することはできません。すべての応答データは、戻り値 Task(T) によって渡される必要があります。
私はこのインターフェイスをAsyncWcfLibで使用します。これはアクター ベースのプログラミング モデルをサポートします。

于 2012-04-04T22:17:49.907 に答える
4

Async CTP には、WCF で async/await モデルを使用する方法を示す WCF サンプルがあります。

このモデルを WCF でサポートする計画については、次の投稿を参照してください。

リンク

お役に立てれば。

アマデオ

于 2010-11-13T15:31:40.403 に答える
2

非同期クライアントが同期サービスを呼び出すことは非常に一般的です。
次のクライアントとサービス コントラクトが一致します (舞台裏で少し魔法が使われています)。

    [ServiceContract( Namespace="X", Name="TheContract" )]
    public interface IClientContractAsynchronous
    {
        [OperationContract]
        Task<TResponse> SendReceiveAsync( TRequest req );
    }

    [ServiceContract( Namespace="X", Name="TheContract" )]
    public interface IServiceContractSynchronous
    {
        [OperationContract]
        TResponse SendReceive( TRequest req );
    }

クライアント インターフェイスは直接待機可能です。

   var response = await client.Channel.SendReceiveAsync( request );

オペレーション コントラクトでoutまたはrefパラメーターを使用することはできません。すべての応答データを戻り値で渡す必要があります。これは実際、私にとって重大な変更でした。
私はこのインターフェイスをAsyncWcfLibで使用します。これはアクター ベースのプログラミング モデルをサポートします。

于 2012-03-22T19:44:06.140 に答える
2

Matt が述べたように、 /ペアから aTaskFactory.FromAsyncを作成できる方法があります。WCF 参照を追加するときに非同期エンドポイントを有効にする必要があります。その後、拡張メソッドを使用してそれらを自分でラップできます。TaskBeginEnd

Amadeo が述べたように、(C# WCF) Stock Quotesディレクトリの下の Async CTP にこのサンプルがあります。

また、そのディレクトリにTaskWsdlImportExtensionプロジェクトがあります。その dll への参照を追加し、.config を次のように変更します。

<configuration>
 <system.serviceModel>
  <client>
   <metadata>
    <wsdlImporters>
     <extension type="TaskWsdlImportExtension.TaskAsyncWsdlImportExtension, TaskWsdlImportExtension" />
    </wsdlImporters>
   </metadata>
  </client>
 </system.serviceModel>
</configuration>

そうすれば、独自のラッピングを行う必要はまったくありません。あなたのTaskWsdlImportExtensionためにそれを行います。

于 2011-08-30T14:17:03.320 に答える
1

async/await は、Task および Task を返すメソッドを中心に構築されていることを正しく指摘してください (async/await の動作の詳しい説明については、こちらを参照してください)。WCF サービスのタスク ベースのメソッドを生成する方法は次のとおりです。

  1. Visual Studio 2012 RC の [サービス参照の構成] ダイアログ ボックスには、[タスク ベースの操作を生成する] という追加のチェック ボックスがあります。そのオプションがMSDNに記載されていることはわかりませんが、特に WCF 呼び出しでシームレスな async/await を許可するために存在すると思います。

  2. 以前のバージョンについては、CTP を使用しても WCF で Task<> ベースのメソッドを生成できる拡張機能について説明しているこの投稿をご覧ください。

于 2012-08-09T00:00:02.530 に答える