6

私はWCFを学び、さまざまなことを試しています。

次のサービスを設定しました。

[ServiceBehavior(IncludeExceptionDetailInFaults = true , 
    InstanceContextMode = InstanceContextMode.Single)]
    public class TestService : ITestService
    {
        // This operation is defined as OneWay.
        public void Throws()
        {
            throw new ArgumentException();
        }
    }

私は次のようにクライアントからそれを使用します:

var baseAddress = new Uri("net.pipe://localhost/hello");

// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(TestService), baseAddress))
{
    var netBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
    host.AddServiceEndpoint(typeof(ITestService), netBinding, baseAddress);
    host.Open();

    Console.WriteLine("The service is ready at {0}", baseAddress);

    // Create client channel.
    var channel = ChannelFactory<ITestService>.CreateChannel(netBinding, new EndpointAddress(baseAddress));

    ((ICommunicationObject)channel).Open();

    try
    {
        foreach (var i in Enumerable.Range(0, 5000))
        {
            // channel dies after a few attempts.
            channel.Throws();
        }
    }

ThrowsメソッドはIsOneWay=trueとして定義されています。これは、メッセージ(エラーを含む)をクライアントに送信しないことを意味します。

ループで実行している場合、一部の実行後に通信オブジェクトに障害が発生します。その原因がわかりません。

例外の詳細:

System.ServiceModel.CommunicationException:パイプへの書き込み中にエラーが発生しました:パイプが閉じられています。(232、0xe8)。---> System.IO.PipeException:パイプへの書き込み中にエラーが発生しました:パイプが閉じられています。(232、0xe8)。System.ServiceModel.Channels.PipeConnection.StartSyncWrite(Byte []バッファー、Int32オフセット、Int32サイズ、オブジェクトとホルダー)でSystem.ServiceModel.Channels.PipeConnection.Write(Byte []バッファー、Int32オフセット、Int32サイズ、ブール値即時、 TimeSpanタイムアウト、BufferManager bufferManage r)---内部例外スタックトレースの終了---

Throwsメソッドの本体をConsole.WriteLineなどの他のメソッドに変更すると、すべてが正常に実行されていることに注意してください。

編集:サンプルプロジェクトをSkyDriveにアップロードしました:http ://sdrv.ms/NumUbR

誰かがそれをローカルでコンパイルして、同じように動作するかどうかを確認したい場合に備えて。

4

1 に答える 1

5

ある時点で利用可能な帯域幅を単に超えています。それはおそらくパイプですが、WCF スタックにもある可能性があります...例外の処理にはコストがかかり、5000 個の例外をできるだけタイトなループで実行しています。例外からWriteLine()何も返さない に変更すると、必要な帯域幅/処理が劇的に減少するため、問題が修正されます。(OneWay について言及されているようですが、あまり変わらないと思います。例外が返されなくても、処理する必要があります)。

InstanceContextMode を PerCall に変更してみてください。これは、「大量」サービスの標準設定です。混雑が少し緩和されます。

また、コメントに対処するために、このようなサービスをホストすることは問題ありません. ServiceHost は独自のスレッドを管理します。

于 2012-08-13T21:19:01.913 に答える