Disposing WCF with long running [OperationContract(IsOneWay = true)]

1.6k Views Asked by At

I've following service, defined as OneWay, because it's long running (a few minutes) and I can't wait when it finishes (it's used in ASP.NET application).

The problem is that if I call client.Dispose() after the service call, it blocks and after 60s timeout expires with exception.

How should I dispose the client in such scenario? Increasing the timeout of the service isn't solution, because I can't wait so long time with the HTTP request of the web page, where it's used.

[ServiceContract]
public interface IMyService
{        
    [OperationContract(IsOneWay = true)]
    void BeginRun();
}

var client = new MyServiceClient();
client.BeginRun();
client.Close(); //This leads to time-out, how and when to call it?

Thanks for tips.

4

There are 4 best solutions below

0
Chris On BEST ANSWER

From your signiture, it seems like you don't need any sort of response. In that case, on the service, when you recieve the BeginRun() call, execute the work on a non-WCF thread. This will free the channel & should allow you to immediately dispose the client.

Even though you've marked the OperationContract as IsOneWay, that doesn't mean WCF immediately releases the channel. A WCF service will not actually return from a one-way call until all of the data has been read from the wire. Depending on your service configuration, this could involve waiting for previous calls to complete (particularly w/ Single concurrency mode sessionful service configurations).

So, for several reasons it's often a good idea to actually execute service work on a separate thread from the WCF thread, which should improve throughput. Take a look at this article on MSDN for additional details.

0
schglurps On

You can try the IChannel approach. Or maybe try this, not sure this will work : http://msdn.microsoft.com/en-us/library/ms731177.aspx

2
Sajeetharan On

You need to add try catch block inside your code and if there is an timeout exception it should abort the client.

        try
        {
            work(client);
            client.Close();
        }

        catch (Exception e)
        {
            client.Abort();
            throw;
        }
0
tom redfern On

I would switch your binding to netMsmqBinding. Then from your client your one-way calls will be instantaneous.

Long duration sends over http are problematic at best and complex to manage. Sticking a queue in between will greatly simplify this operation.