WCF ServiceContract method returns task <T> and timeout
I am new to WCF. I am doing a service in which I need to calculate a long operation. Since the method is long, I thought I could perform the async operation by returning the task. But that does not work. I am still getting a timeout exception. Sample code (not my actual code) demonstrating my problem below:
[ServiceContract] public interface ICalculator { [OperationContract] Task<double> ComputePiAsync(ulong numDecimals); } internal class Calculator : ICalculator { public async Task<double> ComputePiAsync(ulong numDecimals) { return await SomeVeryVeryLongWayOfComputingPi(numDecimals); } } // server using (var host = new ServiceHost(typeof(Calculator), new Uri("net.pipe://localhost"))) { host.AddServiceEndpoint(typeof(ICalculator), new NetNamedPipeBinding(), "Calculator"); host.Open(); Console.WriteLine("Service is running. Press <ENTER> to exit."); Console.ReadLine(); host.Close(); } // client var factory = new ChannelFactory<ICalculator>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/Calculator")); var calculator = factory.CreateChannel(); await calculator.ComputePiAsync(numDecimals); // <--- this call takes longer than 1 minute and I'm getting a timeout here. So what should I do to cause a long operation on my service and wait for the result asynchronously? Increase timeout? If I increase the work timeout, then what's the point of returning the Task method?
Since the method is long, I thought I could do the async operation
Hold, slow down - you mix asynchrony with a network timeout.
Consider asynchronism first:
1. Using async/await to asynchronously invoke a WCF service from a client
client-side async/await helps us write an asynchronous program so that the application remains responsive - in the case of, say, WPF/WinForm , we donβt want to freeze the user interface by invoking the WCF service synchronously in the user interface thread. Instead, we can call it asynchronously using async/await . The magic here is that it is full functionality on the client side, that is, the service should not be asynchronous or should not return Task - all that you need while the service reference(proxy) , you must tell Visual Studio to generate the Task based on asynchronous operations - and then you can use async/await on your client.
2. Then What is the need for async/await on the service side?
The service itself can fulfill some I/O request to some data source or, in turn, call another service. Using async/await from the service side - the service can perform these operations asynchronously - without blocking any service flows. Which means that the service has more free streams to serve new customers, therefore, scaling services is much better.
Now, above two, should not be confused with the long service
When your service takes a long time to get results, you are dealing with network timeouts. You cannot and should not try to keep your network connection open indefinitely without any action. WCF helps you with this by setting various timeouts. If your service method takes a long time to respond, you will have to increase these timeouts. You may consider using WCF callback contracts if you want to report progress to the client. If this is not enough for your requirement, reconfigure your service so that the client can initiate a lengthy process, and then call another service method to request status.
First, you must be sure that the problem is a truly asynchronous call. Try to call the service synchronously to make sure the call is successful.
Assuming your problem is actually an async operation, you should use the IAsyncResult WCF instead of async , as this is the standard way to handle asynchronous operations in WCF. You will need an operation to start the service, and another to process the results.
I could write some code, but here are some good posts that explain my point in detail and deserve attention:
- Creating an ASP.NET service for Async in .NET 4.5 (in this example, the word
asynccomes before the WCF service and the job is used to perform an operation inside a WCF call. It can be useful if several asynchronous calls are made to the server) - A practical guide. Implement an Asynchronous Service Operation
- Asynchronous communication in WCF service
Another tip:
After completing these steps, if you understand that the client needs more time to process the asynchronization execution, consider increasing the
operation timeoutto wait longer for a return. If the connection is unstable, consider increasingopen timeoutto provide the client with more time to establish a connection.
Hope this helps.