良い質問。クライアント アプリケーションは、メソッドを呼び出す前にチャネルを開きます。チャネルはすべてのデータ通信に使用されます。送信には 2 つの方法があります: 1) 信頼できるセッション - パケットが確実に配信され、クラックされたパケットが再送信される場合、2) 順序付け - サービスのリクエストがクライアントから転送された順序で計算される場合 (配信方法ではありません) . 信頼性の高い順序付けされたセッションがあり、アプリケーションを閉じた後にサービスホストがデータに問題を抱えている場合、ホストはクライアントに再送信データを要求しようとし、応答がない場合、要求したものをすべて拒否します。他の状況(信頼できない)では、チャネルを開いた後、データを送信して通信を破棄できます。例外がなければ、一方向メソッドがリクエストを計算します。
サービスの問題でいくつかの可能性をテストするために(正確にはクライアントのパロブレムではありませんが、役に立ちます)、解決策を作成します:
1) 1 つのファイル「IService1.cs」を含むライブラリ プロジェクト「WcfContracts」:
[ServiceContract]
public interface IService1
{
[OperationContract]
void ThrowException();
[OperationContract(IsOneWay=true)]
void ThrowExceptionUseIsOneWay();
}
2) 2 つの「WcfContracts」を参照するコンソール プロジェクト「WcfConsoleHoster」は、次の 3 つのファイルで構成されます。
a) サービスの実装である Service1.cs
public class Service1 : WcfContracts.IService1
{
public void ThrowException()
{
throw new Exception("Basic exception");
}
public void ThrowExceptionUseIsOneWay()
{
throw new Exception("Basic exception using IsOneWay=true");
}
}
b) デフォルトのエントリ ポイントがあり、サービスを開始するだけの Program.cs
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service1));
host.Open();
Console.WriteLine("host 1 opened");
Console.ReadKey();
}
c) サービス「App.config」
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="behavourHttpGet" name="WcfConsoleHoster.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfConsoleHoster/Service1/" />
</baseAddresses>
</host>
<endpoint binding="wsHttpBinding" contract="WcfContracts.IService1" />
<endpoint address ="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behavourHttpGet">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
3) サービスを呼び出すだけのコンソール プロジェクト「WcfConsoleClient」
a) 「Program.cs」内
Console.WriteLine("Wcf client. Press any key to start");
Console.ReadKey();
ChannelFactory<IService1> factory = new ChannelFactory<IService1>("Service1_Endpoint");
IService1 channel = factory.CreateChannel();
//Call service method
channel.ThrowException();
Console.WriteLine("Operation executed");
Console.ReadKey();
b) クライアント「App.config」
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint name="Service1_Endpoint"
address="http://localhost:8732/Design_Time_Addresses/WcfConsoleHoster/Service1/"
binding="wsHttpBinding"
contract="WcfContracts.IService1">
</endpoint>
</client>
</system.serviceModel>
</configuration>
1.例外をスローします。まず、サーバー ホストで例外をスローする双方向メソッドを呼び出します。次に、この例外はクライアントに戻り、チャネルはクライアント側でそれを発生させ、アプリケーションは破棄されます。もちろん、これは try()catch{} ブロックで処理できます。
を呼び出して一方向メソッドで同じように見てみましょうchannel.ThrowExceptionUseIsOneWay();
。サービス ホストで例外が発生しますが、クライアント側では例外が発生せず、「操作が実行されました」と表示されます。チャネルは次回使用できなくなることを認識しておくことが重要です。
したがってIsOneWay=true
、期待どおりに機能します-メッセージは一方向にのみ送信されます。メソッドからオブジェクトを返すことはできず (void が想定されます)、FaultContract を使用したり、サービスの起動後に InvalidOperationException を取得したりすることはできません。
2.Thread.Sleep()。次のテストは、での大規模な操作Thread.Sleep()
です。
IService1
に拡張されます
[OperationContract]
int ThreadSleep();
[OperationContract(IsOneWay=true)]
Service1.cs の実現は5 秒間待機しています。
public int ThreadSleep()
{
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
return 1;
}
public void ThreadSleepUseIsOneWay()
{
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
}
経過した呼び出し時間をカウントするためのクライアントの少しの変更
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
//call methode
channel.ThreadSleep();
stopwatch.Stop();
Console.WriteLine(string.Format("Operation executed in {0} seconds", stopwatch.Elapsed.Seconds));
Console.ReadKey();
双方向メソッド を呼び出すThreadSleep()
と、「7 秒で操作が実行されました」という結果が得られます (スレッドのスリープに 5 秒 + チャネルの初期化に 2 秒)。
One way method
with 呼び出しchannel.ThreadSleepUseIsOneWay()
の結果は「0秒」です! サービスの応答を待つ必要はありません。
同じマシン上で信頼性が高く高速な接続であるNetNamedPipeBindingを使用することをお勧めします。