5

スレッドで (バックグラウンドで) プロキシを開こうとしています。スレッドはプロキシの新しいインスタンスを作成し、サービスのメソッドを呼び出し、その直後にサービスを破棄します。

これはすべてスレッドで発生します。

var background = new Thread(() =>
{
    var proxy = new AssignmentSvcProxy(new EndpointAddress(worker.Address));              

    try
    {
        proxy.Channel.StartWork(workload);
        proxy.Dispose();                   
    }
    catch (EndpointNotFoundException ex)
    {
        logService.Error(ex);                        
        proxy.Dispose();
        proxy = null;
    }
    catch (CommunicationException ex)
    {
        logService.Error(ex);
        proxy.Dispose();
        proxy = null;
    }
    catch (TimeoutException ex)
    {
        logService.Error(ex);                    
        proxy.Dispose();
        proxy = null;
    }
    catch (Exception ex)
    {
        logService.Error(ex);                    
        proxy.Dispose();
        proxy = null;
    }                

}) { IsBackground = true };

background.Start();

CloseTimeout、OpenTimeout、ReceiveTimeout、SendTimeout のタイムアウトを最大に設定しても、断続的なタイムアウトの問題が発生し続けます。

設計上、これが問題ではないことを確認したいだけです。つまり、スレッドでサービスを開いて破棄しますか?

編集 :

プロキシは、スレッドごとに異なるエンドポイントでカスタム バインディングを使用してチャネルを内部的に確立します。

4

1 に答える 1

6

問題は、プロキシを適切に閉じていないことにあると思います。多数のスレッドがサーバーにアクセスしていて、すべてがクリーンアップされていない場合、それらの接続でタイムアウトが発生する可能性があります。

Dispose は、接続を閉じるのには適していません。詳細はこちら:プロキシの破棄

使用する理想的なパターンは次のとおりです。

try
{
    proxy.Close();
}
catch (Exception ex)
{
    proxy.Abort();
}
finally
{
    proxy = null;
}

接続を閉じようとして失敗すると、すべての接続が中止されます。例外が発生した場合、Dispose は中止されません。

そのため、次のようにリファクタリングします。

var background = new Thread(() =>
{
     var proxy = new AssignmentSvcProxy(new EndpointAddress(worker.Address));              

    try
    {
        proxy.Channel.StartWork(workload);
    }
    catch (Exception ex)
    {
        // You aren't doing anything special with your specific exception types
        logService.Error(ex);                    
    }                
    finally
    {
        try
        {
            proxy.Close();
        }
        catch (Exception ex)
        {
            proxy.Abort();
        }
        finally
        {
            proxy = null;
        }
    }

}) { IsBackground = true };

background.Start();
于 2012-11-06T19:06:35.973 に答える