2

わかりました、私は WCF サービスを持っていますが、これはかなり厄介な方法で動作しています。問題は、サービス メソッドを呼び出すと、次のようになります。

using (var wcf = new Wcf<IDroneService>("http://test.group.com/DroneService.svc"))
{
    wcf.Channel.StartLoadTest(scenario);
}

要求が 1 分後にタイムアウトになるまで何も起こりませんが、例外がスローされた後にのみ、WCF サービス (IIS でホストされている) が開始されます。つまり、実際にそのアセンブリが読み込まれ、Application_Start が実行され、サービスのインスタンスがサーバー側のエンドポイントなどで、リクエストを適切に受け取り、実行します。ただし、これは、リクエストがタイムアウトして例外がスローされた後にのみ発生ます。

これは、クライアントとサーバーの両方のバインドを構成する方法です。

public class WcfConfigurator
{
    public Binding GetBinding()
    {
        var basic = new BasicHttpBinding
        {
            MaxBufferSize = int.MaxValue,
            MaxBufferPoolSize = int.MaxValue,
            MaxReceivedMessageSize = int.MaxValue,
            TransferMode = TransferMode.Streamed,
            ReceiveTimeout = TimeSpan.FromSeconds(30),
            ReaderQuotas =
            {
                MaxDepth = int.MaxValue,
                MaxStringContentLength = int.MaxValue,
                MaxArrayLength = int.MaxValue,
                MaxBytesPerRead = int.MaxValue,
                MaxNameTableCharCount = int.MaxValue
            }
        };
        return basic;
    }

    public void ConfigureBehavior(ServiceEndpoint endpoint)
    {
        foreach (OperationDescription op in endpoint.Contract.Operations)
        {
            var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
            if (dataContractBehavior != null)
            {
                dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }
    }

    public void ConfigureBehavior(KeyedByTypeCollection<IServiceBehavior> behaviors)
    {
        var serviceDebugBehavior = behaviors.Find<ServiceDebugBehavior>();
        if (serviceDebugBehavior != null)
        {
            serviceDebugBehavior.IncludeExceptionDetailInFaults = Config.Wcf.ExceptionDetails;
        }
    }
}

サーバー側でも同じプログラム構成を使用して、エンドポイントを構築します。この問題は封筒が大きい場合にのみ発生します。封筒が小さい場合は問題ありません。

Wcf チャネルの構成に何か不足していますか? Wcf<T>は単なるラッパーChannelFactory.CreateChannelです。WCF サーバーでは、Windsor WcfIntegration 機能を使用して、プログラムでも構成します。このような:

public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
    ServiceHostBase serviceHost = base.CreateServiceHost(constructorString, baseAddresses);
    return ConfiguredServiceHost(serviceHost);
}

private T ConfiguredServiceHost<T>(T serviceHost) where T : ServiceHostBase
{
    serviceHost.AddDefaultEndpoints();

    wcfConfigurator.ConfigureBehavior(serviceHost.Description.Behaviors);

    foreach (ServiceEndpoint endpoint in serviceHost.Description.Endpoints)
    {
        endpoint.Binding = wcfConfigurator.GetBinding();
        wcfConfigurator.ConfigureBehavior(endpoint);
    }
    return serviceHost;
}

これがサーバー側の問題だとは思いませんが (少なくとも今のところは問題ありません)、前述のように、エンベロープが大きすぎると (要求がタイムアウトするまで) WCF サーバーのシンボルが読み込まれないためです。 、とにかく処理されます)。

以前にこの奇妙な問題に遭遇した人はいますか?

4

2 に答える 2

0

私のWCFの経験から、WCFエラーの予測と診断は困難であり、広範なログ記録とWCFトレースを有効にして詳細な調査を行う必要があります。クライアント/サーバーサービスのタイムアウトの構成に誤りがあるように感じます。したがって、最新バージョンのFiddlerをインストールし、何が起こっているか、どの要求が送信されたか、応答が送信されたかどうかを確認します。また、を使用してWCFトレースを有効switchLevel="All"にします。ほとんどの場合、WCFトレースログは問題を明示的に示します。

あなたは1分について言及しました...

WCFのタイムアウトとそのデフォルト値

これらは最もよく知られているタイムアウトです。SendTimeout、、、 および。ReceiveTimeout_ これらは、バインディングの構成またはコードを介して簡単に設定できます。それらのデフォルト値は1分ですOpenTimeoutCloseTimeout

値を明示的に増やしてみてください。ただし、最初に、接続を確立するのに1分で十分なので、問題が何であるか、なぜ表示されるのかを理解することをお勧めします。

于 2012-11-28T21:12:58.490 に答える
0

以前に WCF で同様の問題が発生したことがあり、サービスを利用するときに ChannelFactory を使用するようになりました。エラーを説明していないことはわかっていますが、試してみる価値があるかもしれません。これが私がそれをした方法です:

internal static class ServiceObjects
{
    public static ISomeService SomeSVC { get { return GetSomeServiceClient(); }

    private static BasicHttpBinding _Binding = new BasicHttpBinding("SomeBasicHttpBindingEndpoint"); 
    private static EndpointAddress _Endpoint = new EndpointAddress(new Uri("http://test.helloworld.com/SomeService.svc"));

    private static IDocManagerService GetDocServiceClient()
    {
        ChannelFactory<ISomeService> _someSvcFactory = new ChannelFactory<ISomeService>(_Binding, _Endpoint);

        foreach (OperationDescription op in _someSvcFactory.Endpoint.Contract.Operations)
        {
            DataContractSerializerOperationBehavior _dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;

            if (_dataContractBehavior != null)
            {
                _dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }

        return _someSvcFactory.CreateChannel();
    }
}

そしてサービスを消費します:

ServiceObjects.SomeSVC.SomeMethod()
于 2013-01-16T09:16:24.860 に答える