同期操作と非同期操作Synchronous and Asynchronous Operations

ここでは、非同期サービス操作の実装と呼び出しについて説明します。This topic discusses implementing and calling asynchronous service operations.

多くのアプリケーションは、メソッド呼び出しの実行中に有用な処理を続行できるように、メソッドを非同期的に呼び出します。Many applications call methods asynchronously because it enables the application to continue doing useful work while the method call runs. Windows Communication Foundation (WCF) サービスとクライアント アプリケーションの WCF アプリケーションの対話機能に対してバランスの取れたスループットを最大化するより高い柔軟性を提供する 2 つの異なるレベルでの操作の非同期呼び出しに参加できます.Windows Communication Foundation (WCF) services and clients can participate in asynchronous operation calls at two distinct levels of the application, which provide WCF applications even more flexibility to maximize throughput balanced against interactivity.

非同期操作の種類Types of Asynchronous Operations

すべてのサービスは、パラメーターの型に関係なく、WCF では、コントラクト、戻り値と WCF 属性を使用して、クライアントとサービス間の特定のメッセージ交換パターンを指定します。All service contracts in WCF, no matter the parameters types and return values, use WCF attributes to specify a particular message exchange pattern between client and service. WCF は、適切なサービス操作の実行中のクライアント コードを自動的に受信および送信メッセージをルーティングします。WCF automatically routes inbound and outbound messages to the appropriate service operation or running client code.

クライアントが所有するのは、特定操作のメッセージ交換パターンが指定されたサービス コントラクトのみです。The client possesses only the service contract, which specifies the message exchange pattern for a particular operation. 基盤となるメッセージ交換パターンに従っている限り、クライアントは選択する任意のプログラミング モデルを開発者に提供できます。Clients can offer the developer any programming model they choose, so long as the underlying message exchange pattern is observed. 同様に、サービスも、指定されたメッセージ パターンに従っている限り、任意の方法で操作を実装できます。So, too, can services implement operations in any manner, so long as the specified message pattern is observed.

サービスまたはクライアントのいずれかの実装からサービス コントラクトの独立性には、WCF アプリケーションの非同期実行の次の形式が有効にします。The independence of the service contract from either the service or client implementation enables the following forms of asynchronous execution in WCF applications:

  • クライアントは、同期メッセージ交換を使用して要求/応答操作を非同期に呼び出すことができます。Clients can invoke request/response operations asynchronously using a synchronous message exchange.

  • サービスは、同期メッセージ交換を使用して要求/応答操作を非同期に実装できます。Services can implement a request/response operation asynchronously using a synchronous message exchange.

  • クライアントまたはサービスの実装に関係なく、一方向のメッセージ交換が可能です。Message exchanges can be one-way, regardless of the implementation of the client or service.

推奨される非同期シナリオSuggested Asynchronous Scenarios

操作のサービス実装でブロッキング呼び出し (I/O 処理の実行など) を作成する場合は、サービス操作の実装で非同期手法を使用します。Use an asynchronous approach in a service operation implementation if the operation service implementation makes a blocking call, such as doing I/O work. 非同期操作を実装している場合、非同期の操作とメソッドを呼び出して、できるだけ非同期呼び出しパスを拡張するようにします。When you are in an asynchronous operation implementation, try to call asynchronous operations and methods to extend the asynchronous call path as far as possible. たとえば、BeginOperationTwo() 内から BeginOperationOne() を呼び出します。For example, call a BeginOperationTwo() from within BeginOperationOne().

  • 次のような場合には、クライアントまたは呼び出し元アプリケーションで非同期手法を使用します。Use an asynchronous approach in a client or calling application in the following cases:

  • 中間層アプリケーションから操作を呼び出す場合 If you are invoking operations from a middle-tier application. (このようなシナリオの詳細については、次を参照してください中間層クライアント アプリケーション。)。(For more information about such scenarios, see Middle-Tier Client Applications.)

  • ASP.NET ページ内で操作を呼び出す場合、非同期ページを使用します。If you are invoking operations within an ASP.NET page, use asynchronous pages.

  • 1 つは、任意のアプリケーションから操作を呼び出す場合は、Windows フォームや Windows Presentation Foundation (WPF) などスレッド。If you are invoking operations from any application that is single threaded, such as Windows Forms or Windows Presentation Foundation (WPF). イベント ベースの非同期呼び出しモデルを使用すると、結果イベントが UI スレッドで発生するので複数のスレッドを独自に処理する必要がなく、アプリケーションの応答性が向上します。When using the event-based asynchronous calling model, the result event is raised on the UI thread, adding responsiveness to the application without requiring you to handle multiple threads yourself.

  • 一般に、同期呼び出しと非同期呼び出しのいずれかを選択する場合は、非同期呼び出しを選択します。In general, if you have a choice between a synchronous and asynchronous call, choose the asynchronous call.

非同期サービス操作の実装Implementing an Asynchronous Service Operation

非同期操作は、次の 3 つの方法のいずれかを使用して実装できます。Asynchronous operations can be implemented by using one of the three following methods:

  1. タスク ベースの非同期パターンThe task-based asynchronous pattern

  2. イベント ベースの非同期パターンThe event-based asynchronous pattern

  3. IAsyncResult 非同期パターンThe IAsyncResult asynchronous pattern

タスク ベースの非同期パターンTask-Based Asynchronous Pattern

非同期操作を実装する方法としては、最も直接的でわかりやすいタスク ベースの非同期パターンが推奨されます。The task-based asynchronous pattern is the preferred way to implement asynchronous operations because it is the easiest and most straight forward. このメソッドを使用してサービス操作を実装し、タスクの戻り値の型を指定するだけ<T > ここで T は論理操作によって返される型です。To use this method simply implement your service operation and specify a return type of Task<T>, where T is the type returned by the logical operation. 例えば:For example:

public class SampleService:ISampleService   
{   
   // ...  
   public async Task<string> SampleMethodTaskAsync(string msg)   
   {   
      return Task<string>.Factory.StartNew(() =>   
      {   
         return msg;   
      });   
   }  
   // ...  
}  

SampleMethodTaskAsync 操作は、タスクを返します<文字列 > ため、論理操作は、文字列を返します。The SampleMethodTaskAsync operation returns Task<string> because the logical operation returns a string. タスク ベースの非同期パターンの詳細については、次を参照してください。タスク ベースの非同期パターンです。For more information about the task-based asynchronous pattern, see The Task-Based Asynchronous Pattern.

警告

タスク ベースの非同期パターンを使用している場合、操作の完了を待機している間に例外が発生すると T:System.AggregateException がスローされる場合があります。When using the task-based asynchronous pattern, a T:System.AggregateException may be thrown if an exception occurs while waiting on the completion of the operation. この例外は、クライアントまたはサービスで発生することがあります。This exception may occur on the client or services

イベント ベースの非同期パターンEvent-Based Asynchronous Pattern

イベント ベースの非同期パターンをサポートするサービスには、MethodNameAsync という名前の操作が 1 つ以上含まれます。A service that supports the Event-based Asynchronous Pattern will have one or more operations named MethodNameAsync. これらのメソッドは、同期バージョンに対応するもので、現在のスレッドで同じ操作を行います。These methods may mirror synchronous versions, which perform the same operation on the current thread. クラスには、MethodNameCompleted イベントや MethodNameAsyncCancel メソッド (または単に CancelAsync メソッド) が含まれる場合もあります。The class may also have a MethodNameCompleted event and it may have a MethodNameAsyncCancel (or simply CancelAsync) method. 操作の呼び出し元のクライアントは、操作の完了時に呼び出されるイベント ハンドラーを定義します。A client wishing to call the operation will define an event handler to be called when the operation completes,

次のコードは、イベント ベースの非同期パターンを使用して非同期操作を宣言する方法を示します。The following code snippet illustrates how to declare asynchronous operations using the event-based asynchronous pattern.

public class AsyncExample  
{  
    // Synchronous methods.  
    public int Method1(string param);  
    public void Method2(double param);  

    // Asynchronous methods.  
    public void Method1Async(string param);  
    public void Method1Async(string param, object userState);  
    public event Method1CompletedEventHandler Method1Completed;  

    public void Method2Async(double param);  
    public void Method2Async(double param, object userState);  
    public event Method2CompletedEventHandler Method2Completed;  

    public void CancelAsync(object userState);  

    public bool IsBusy { get; }  

    // Class implementation not shown.  
}  

イベント ベースの非同期パターンの詳細については、次を参照してください。イベント ベースの非同期パターンです。For more information about the Event-based Asynchronous Pattern, see The Event-Based Asynchronous Pattern.

IAsyncResult 非同期パターンIAsyncResult Asynchronous Pattern

.NET Framework.NET Framework 非同期プログラミング パターンを使用し、<Begin> プロパティが AsyncPattern に設定されている true メソッドを使用することで、サービス操作を非同期に実装できます。A service operation can be implemented in an asynchronous fashion using the .NET Framework.NET Framework asynchronous programming pattern and marking the <Begin> method with the AsyncPattern property set to true. この場合の非同期操作は、同期操作と同じ形式でメタデータに公開されます。つまり、要求メッセージとそれに関連する応答メッセージを伴う単独操作として公開されます。In this case, the asynchronous operation is exposed in metadata in the same form as a synchronous operation: It is exposed as a single operation with a request message and a correlated response message. このとき、クライアント プログラミング モデルは選択が可能です。Client programming models then have a choice. サービスが呼び出されたときに要求/応答メッセージ交換が行われていれば、クライアント プログラミング モデルは、このパターンを同期操作または非同期操作として表すことができます。They can represent this pattern as a synchronous operation or as an asynchronous one, so long as when the service is invoked a request-response message exchange takes place.

一般に、システムの非同期の性質を考えると、スレッドへの依存は避ける必要があります。In general, with the asynchronous nature of the systems, you should not take a dependency on the threads. 操作のディスパッチ処理のさまざまな段階にデータを渡す最も信頼性の高い方法は、拡張機能を使用する方法です。The most reliable way of passing data to various stages of operation dispatch processing is to use extensions.

例については、次を参照してください。する方法: 非同期サービス操作を実装するです。For an example, see How to: Implement an Asynchronous Service Operation.

クライアント アプリケーションでの呼び出し方法に関係なく、非同期に実行するコントラクト操作 X を定義するには次の処理を実行します。To define a contract operation X that is executed asynchronously regardless of how it is called in the client application:

  • パターン BeginOperationEndOperation を使用する 2 つのメソッドを定義します。Define two methods using the pattern BeginOperation and EndOperation.

  • BeginOperation メソッドには操作のための in パラメーターと ref パラメーターがあり、IAsyncResult 型を返します。The BeginOperation method includes in and ref parameters for the operation and returns an IAsyncResult type.

  • EndOperation メソッドには IAsyncResult パラメーター、out パラメーター、および ref パラメーターがあり、操作の戻り値の型を返します。The EndOperation method includes an IAsyncResult parameter as well as the out and ref parameters and returns the operations return type.

たとえば、次のメソッドを参照してください。For example, see the following method.

int DoWork(string data, ref string inout, out string outonly)  
Function DoWork(ByVal data As String, ByRef inout As String, _out outonly As out) As Integer  

非同期操作を作成するには、2 つのメソッドを次のように記述します。To create an asynchronous operation, the two methods would be:

[OperationContract(AsyncPattern=true)]IAsyncResult BeginDoWork(string data,                           ref string inout,                           AsyncCallback callback,                           object state);int EndDoWork(ref string inout, out string outonly, IAsyncResult result);  
<OperationContract(AsyncPattern := True)>  _Function BeginDoWork(ByVal data As String, _                 ByRef inout As String, _                 ByVal callback As AsyncCallback, _                 ByVal state As Object) _As IAsyncResult Function EndDoWork(ByRef inout As String, _        ByRef outonly As String, _        ByVal result As IAsyncResult) _As Integer  

注意

OperationContractAttribute 属性は、BeginDoWork のメソッドにのみ適用されます。The OperationContractAttribute attribute is applied only to the BeginDoWork method. 生成されるコントラクトには、DoWork という名前の WSDL 操作が 1 つ含まれます。The resulting contract has one WSDL operation named DoWork.

クライアント側の非同期呼び出しClient-Side Asynchronous Invocations

WCF クライアント アプリケーションは、任意の前に説明した 3 つの非同期呼び出しモデルを使用できます。A WCF client application can use any of three asynchronous calling models described previously

タスク ベースのモデルを使用する場合は、次のコードに示すように、await キーワードを使用して操作を呼び出すだけです。When using the task-based model, simply call the operation using the await keyword as shown in the following code snippet.

await simpleServiceClient.SampleMethodTaskAsync("hello, world");  

イベント ベースの非同期パターンを使用する場合は、応答の通知を受信するイベント ハンドラーを追加するだけで済み、結果イベントはユーザー インターフェイス スレッドで自動的に発生します。Using the event-based asynchronous pattern only requires adding an event handler to receive a notification of the response -- and the resulting event is raised on the user interface thread automatically. このアプローチを使用するには、両方を指定、 /async/tcv:Version35コマンドとオプション、 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe)次のように、例です。To use this approach, specify both the /async and /tcv:Version35 command options with the ServiceModel Metadata Utility Tool (Svcutil.exe), as in the following example.

svcutil http://localhost:8000/servicemodelsamples/service/mex /async /tcv:Version35  

これは、Svcutil.exe は、イベント インフラストラクチャを実装し、応答を受信し、適切な操作をイベント ハンドラーを割り当てるには、呼び出し元のアプリケーションを有効にすると WCF クライアント クラスを生成します。When this is done, Svcutil.exe generates a WCF client class with the event infrastructure that enables the calling application to implement and assign an event handler to receive the response and take the appropriate action. 完全な例では、次を参照してください。する方法: サービスの操作を非同期に呼び出すです。For a complete example, see How to: Call Service Operations Asynchronously.

イベント ベースの非同期モデルは、.NET Framework version 3.5.NET Framework version 3.5 でのみ使用できます。The event-based asynchronous model, however, is only available in .NET Framework version 3.5.NET Framework version 3.5. さらに、これはサポートされていませんでも.NET Framework 3.5.NET Framework 3.5を使用して、WCF クライアント チャネルを作成するときに、System.ServiceModel.ChannelFactory<TChannel>です。In addition, it is not supported even in .NET Framework 3.5.NET Framework 3.5 when a WCF client channel is created by using a System.ServiceModel.ChannelFactory<TChannel>. WCF クライアント チャネル オブジェクトで使用する必要がありますSystem.IAsyncResult操作を非同期で呼び出すオブジェクト。With WCF client channel objects, you must use System.IAsyncResult objects to invoke your operations asynchronously. このアプローチを使用するには指定、 /asyncコマンドとオプション、 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe)次の例のように、します。To use this approach, specify the /async command option with the ServiceModel Metadata Utility Tool (Svcutil.exe), as in the following example.

svcutil http://localhost:8000/servicemodelsamples/service/mex /async   

これにより、対応する <Begin> メソッドを持ち、AsyncPattern プロパティが true に設定された <End> メソッドとして各操作がモデル化されたサービス コントラクトが生成されます。This generates a service contract in which each operation is modeled as a <Begin> method with the AsyncPattern property set to true and a corresponding <End> method. 完全な例を使用するため、ChannelFactory<TChannel>を参照してくださいする方法: 呼び出し操作に非同期的を使用して、チャネル ファクトリです。For a complete example using a ChannelFactory<TChannel>, see How to: Call Operations Asynchronously Using a Channel Factory.

いずれの場合も、サービスが同期的に実装されていても、アプリケーションは操作を非同期に呼び出すことができます。これは、アプリケーションで同じパターンを使用してローカルの同期メソッドを非同期に呼び出す場合と同様です。In either case, applications can invoke an operation asynchronously even if the service is implemented synchronously, in the same way that an application can use the same pattern to invoke asynchronously a local synchronous method. クライアントにとって操作がどのように実装されているかは重要ではありません。応答メッセージが到着すると、その内容がクライアントの非同期 <End> メソッドにディスパッチされ、クライアントは情報を取得します。How the operation is implemented is not significant to the client; when the response message arrives, its content is dispatched to the client's asynchronous <End> method and the client retrieves the information.

一方向メッセージ交換パターンOne-Way Message Exchange Patterns

クライアントまたはサービスが単独で一方向操作 (OperationContractAttribute.IsOneWaytrue に設定されている操作には相関する応答がない) を相手側に送信できる、非同期メッセージ交換パターンを作成することもできます You can also create an asynchronous message exchange pattern in which one-way operations (operations for which the OperationContractAttribute.IsOneWay is true have no correlated response) can be sent in either direction by the client or service independently of the other side. (双方向メッセージ交換パターンを一方向メッセージで使用します)。この場合、サービス コントラクトは、両側が非同期呼び出しまたは非同期実装として実装できる一方向メッセージ交換を指定します。また、状況によっては指定しません。(This uses the duplex message exchange pattern with one-way messages.) In this case, the service contract specifies a one-way message exchange that either side can implement as asynchronous calls or implementations, or not, as appropriate. 一般的に、コントラクトが一方向メッセージ交換の場合、メッセージが送信されるとアプリケーションは応答を待機することなく他の作業を継続できるため、多くの場合、実装が非同期になります。Generally, when the contract is an exchange of one-way messages, the implementations can largely be asynchronous because once a message is sent the application does not wait for a reply and can continue doing other work.

イベント ベースの非同期クライアントとメッセージ コントラクトEvent-based Asynchronous Clients and Message Contracts

イベント ベースの非同期モデルのデザイン ガイドラインには、複数の値を返す場合に、1 つの値を Result プロパティとして返し、残りの値を EventArgs オブジェクトのプロパティとして返すことが記載されています。The design guidelines for the event-based asynchronous model state that if more than one value is returned, one value is returned as the Result property and the others are returned as properties on the EventArgs object. この 1 つの結果として、クライアントがイベント ベースの非同期コマンド オプションを使用してメタデータをインポートし、操作から複数の値が返される場合、既定の EventArgs オブジェクトは 1 つの値を Result プロパティとして返し、残りの値は EventArgs オブジェクトのプロパティになります。One result of this is that if a client imports metadata using the event-based asynchronous command options and the operation returns more than one value, the default EventArgs object returns one value as the Result property and the remainder are properties of the EventArgs object.

メッセージ オブジェクトを受信する場合、Resultプロパティように、そのオブジェクトにプロパティを使用して、返される値であると、 /messageContractコマンド オプション。If you want to receive the message object as the Result property and have the returned values as properties on that object, use the /messageContract command option. これにより、Result オブジェクトの EventArgs プロパティとして応答メッセージを返すシグネチャが生成されます。This generates a signature that returns the response message as the Result property on the EventArgs object. すべての内部戻り値は、応答メッセージ オブジェクトのプロパティになります。All internal return values are then properties of the response message object.

関連項目See Also

IsOneWay
AsyncPattern