一方向のサンプルでは、一方向サービス操作へのサービスのアクセスを示します。 クライアントは、双方向サービス操作の場合と同様に、サービス操作の完了を待機しません。 このサンプルは 作業の開始 に基づいており、 wsHttpBinding
バインドを使用します。 このサンプルのサービスは、要求を受信して処理するサービスを監視できるようにするためのセルフホステッド コンソール アプリケーションです。 クライアントはコンソール アプリケーションでもあります。
注
このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。
一方向のサービス コントラクトを作成するには、サービス コントラクトを定義し、各操作に OperationContractAttribute クラスを適用し、次のサンプル コードに示すように IsOneWay を true
に設定します。
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOneWayCalculator
{
[OperationContract(IsOneWay=true)]
void Add(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Subtract(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Multiply(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Divide(double n1, double n2);
}
クライアントがサービス操作の完了を待機しないことを示すために、このサンプルのサービス コードでは、次のサンプル コードに示すように 5 秒の遅延が実装されています。
// This service class implements the service contract.
// This code writes output to the console window.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
public void Add(double n1, double n2)
{
Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
System.Threading.Thread.Sleep(1000 * 5);
double result = n1 + n2;
Console.WriteLine("Processing Add({0},{1}) - result: {2}", n1, n2, result);
}
...
}
クライアントがサービスを呼び出すと、サービス操作の完了を待たずに呼び出しが戻ります。
サンプルを実行すると、クライアントとサービスのアクティビティが、サービスとクライアントの両方のコンソール ウィンドウに表示されます。 サービスがクライアントからメッセージを受信しているのを確認できます。 各コンソール ウィンドウで Enter キーを押して、サービスとクライアントの両方をシャットダウンします。
先にクライアントが完了してその次にサービスが完了し、クライアントが一方向サービス操作の完了を待たないことが示されます。 クライアントの出力は次のとおりです。
Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25)
Divide(22,7)
Press <ENTER> to terminate client.
次のサービス出力が表示されます。
The service is ready.
Press <ENTER> to terminate service.
Received Add(100,15.99) - sleeping
Received Subtract(145,76.54) - sleeping
Received Multiply(9,81.25) - sleeping
Received Divide(22,7) - sleeping
Processing Add(100,15.99) - result: 115.99
Processing Subtract(145,76.54) - result: 68.46
Processing Multiply(9,81.25) - result: 731.25
Processing Divide(22,7) - result: 3.14285714285714
注
HTTP は、定義上、要求/応答プロトコルです。要求が行われると、応答が返されます。 これは、HTTP 経由で公開される一方向のサービス操作でも当てはまります。 操作が呼び出されると、サービス操作が実行される前に、サービスから HTTP 状態コード 202 が返されます。 この状態コードは、要求が処理のために受け入れられたが、処理がまだ完了していないことを意味します。 操作を呼び出したクライアントは、サービスから 202 応答を受信するまでブロックします。 これにより、セッションを使用するように構成されたバインディングを使用して複数の一方向メッセージが送信されると、予期しない動作が発生する可能性があります。 このサンプルで使用される wsHttpBinding
バインドは、既定でセッションを使用してセキュリティ コンテキストを確立するように構成されています。 既定では、セッション内のメッセージは、送信された順序で到着することが保証されます。 このため、セッション内の 2 番目のメッセージが送信されると、最初のメッセージが処理されるまで処理されません。 その結果、前のメッセージの処理が完了するまで、クライアントはメッセージに対する 202 応答を受信しません。 そのため、クライアントは後続の各操作呼び出しでブロックしているように見えます。 この動作を回避するために、このサンプルでは、処理のために個別のインスタンスにメッセージを同時にディスパッチするようにランタイムを構成します。 このサンプルでは、各メッセージを異なるインスタンスで処理できるように、 InstanceContextMode を PerCall
に設定します。
ConcurrencyMode は、複数のスレッドが一度にメッセージをディスパッチできるように Multiple
に設定されます。
サンプルを設定、ビルド、実行するには
Windows Communication Foundation サンプル のOne-Time セットアップ手順を実行していることを確認します。
ソリューションの C# または Visual Basic .NET エディションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。
単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。
注
クライアントを実行する前にサービスを実行し、サービスをシャットダウンする前にクライアントをシャットダウンします。 これにより、サービスがなくなったため、クライアントがセキュリティ セッションを正常に閉じることができない場合のクライアント例外が回避されます。