在线程上启动多个服务

时间:2012-10-19 15:30:17

标签: c# multithreading wcf socket-timeout-exception

我正在尝试在线程上打开代理(在后台),线程创建代理的新实例,调用服务的方法并在处置服务后立即。

所有这一切都发生在一个主题上:

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的超时设置为max,我仍然会看到间歇性超时问题。

我只是想确保设计明智这不是问题,即在线程上打开服务并处理它?<​​/ p>

编辑:

代理在内部为每个线程在不同端点上建立一个带有自定义绑定的通道。

1 个答案:

答案 0 :(得分:6)

我认为问题可能在于您没有正确关闭代理。如果你有很多线程攻击服务器并且它们并非都在自行清理,你可能会在这些连接上得到一些超时。

处理不是关闭连接的理想选择。更多信息请访问:Disposing proxies

使用的理想模式如下:

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();