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?

+6
source share
2 answers

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.

+12
source

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:

Another tip:

After completing these steps, if you understand that the client needs more time to process the asynchronization execution, consider increasing the operation timeout to wait longer for a return. If the connection is unstable, consider increasing open timeout to provide the client with more time to establish a connection.

Hope this helps.

0
source

Source: https://habr.com/ru/post/950245/


All Articles