Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting multiple services on threads

I am trying to open a proxy on a thread (in background), the thread makes a new instance of the proxy, calls a method of the service and immediately after disposes the service.

All of this happens on a thread :

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

I keep seeing intermittent timeout issues happening even though I have set the timeout to max for CloseTimeout, OpenTimeout, ReceiveTimeout, SendTimeout.

I just want to make sure design wise this is not an issue i.e. opening a service on a thread and disposing it?

EDIT :

Proxy internally establishes a channel with custom binding on different endpoints for each thread.

like image 312
Murtaza Mandvi Avatar asked Oct 19 '12 15:10

Murtaza Mandvi


1 Answers

I think the issue may be in that you are not properly closing the proxies. If you have lots of threads hitting the server and they are not all cleaning up after themselves, you may get some timeouts on those connections.

Dispose is not ideal for closing connections. More information here: Disposing proxies

The ideal pattern to use is as follows:

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

You attempt to close the connection, if it fails, you abort all connections. Dispose does not abort if there is an exception.

As such, I would refactor like so:

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();
like image 50
Bardia Avatar answered Oct 05 '22 02:10

Bardia