0

フォームからWCFサービスを呼び出しています。サービスはIISでホストされています。次の属性を持つサービス:InstanceContextMode.PerSession、ConcurrencyMode = ConcurrencyMode.Multiple

すべての同時呼び出し、インスタンス、およびセッションについて、スロットル動作を最大2000に設定しました。

ただし、200を超えるASynchリクエストを取得できないようです。その後、サービスは応答せず、セッションは最終的にタイムアウトになります。

Asynch呼び出しを使用して、サービスのメソッドを呼び出しています。コードをコピーする

IASyncResult res = Proxy.BeginMethod(endCall、null);

次に、応答をキャッチするために、IASyncResultを受け取り、EndMethod()を介して結果を処理するendCall関数があります。

負荷シミュレーション@1秒のメソッド呼び出しでは、約200回の呼び出しまですべて正常に機能し、その後待機します...(この時点で、これらの200回の呼び出しから199または198の応答があります)。-理論的にはそこにあります。 2つ程度の200の同時セッションであってはなりません。

おそらく、私が行っていないガベージコレクションまたはクロージングがありますか?助言がありますか?

- - アップデート - -

おそらく、プロキシのクローズがスレッドセーフな方法で処理されないという答えが多いと思います。Radikが上記で指摘しているように、プロキシを閉じることは重要ですが、多くのIASyncStateの結果が同時に表示されるため、適切なタイミングで適切な結果を閉じるようにする必要があります。

スレッドからクローズプロキシを起動して、個別に処理できるようにしました。

ThreadPool.QueueUserWorkItem(CloseProxy、ar.AsyncState);

しかし、それはうまくいかないようです。これに関する提案はありますか?

4

1 に答える 1

1

VS でサービス参照を作成すると、生成されたプロキシを使用して、コールバックまたはイベント ハンドラーを使用した 2 つの方法でサービスを非同期に呼び出すことができます。そして、プロキシを閉じることができる2つの異なる場所。ここに小さなサンプルプロジェクト

//close proxy in callback function
private void ButtonCallbackClick(object sender, EventArgs e)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    proxy.BeginDoWork(DateTime.Now.ToShortDateString(), CallBack, proxy);
}

private void CallBack(IAsyncResult ar)
{
    var result = (ar.AsyncState as ServiceClient).EndDoWork(ar);
    if (ar.IsCompleted)
        UpdateView(result);
    CloseProxy(ar.AsyncState);
}
//close proxy in event handler
private void ButtonCompletedClick(object sender, EventArgs e)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    proxy.DoWorkAsync(DateTime.Now.ToShortDateString());
    proxy.DoWorkCompleted += DoWorkCompleted;
}

private void DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
{
    if (e.Error == null)
        UpdateView(e.Result);
    CloseProxy(sender);
}

private static void CloseProxy(object sender)
{
    var proxy = sender as ServiceClient;
    if (proxy == null) return;
    try
    {
        proxy.Close();
    }
    catch (CommunicationException e)
    {
        proxy.Abort();
    }
    catch (TimeoutException e)
    {
        proxy.Abort();
    }
    catch (Exception e)
    {
        proxy.Abort();
    }
}

private static bool _run = false;
//run async query in infinite cycle
private void ButtonCycleClick(object sender, EventArgs e)
{
    _run = !_run;
    if (!_run) return;
    Action<object> action = WaitEvent;
    ThreadPool.QueueUserWorkItem(a => action(action));
}

private void WaitEvent(object action)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    proxy.DoWorkAsync(DateTime.Now.ToShortDateString());
    proxy.DoWorkCompleted += (x, y) => DoWorkCompleted(x, y, action as Action<object>);
}

private void DoWorkCompleted(object sender, DoWorkCompletedEventArgs e, Action<object> action)
{
    if (!_run)
        return;

    if (e.Error == null)
        UpdateView(e.Result);
    CloseProxy(sender);
    action(action);
}
于 2011-09-17T21:22:11.650 に答える