I have one app (UWP - Win10) and a Windows service.
The service is running in background, and they were both developed in C#. "callAsync" is the method on the service. I am using await to call it on the client.
var obj = await callAsync(10);
The problem is: If this call takes less than 1min40s (100 seconds), then everything works ok. But if it takes more than 1min40s, then an exception will occur "TaskCanceledException: A task was canceled".
I have search SO and the web but still could not find any indication on how to resolve this "timeout" issue. I have added all the "open/close/receive/send" timeout flags on both app and service app.config, although the exception that is thrown in that case is different.
If I try with a simple delay in the client:
await Task.delay(200000);
it works properly.
This service was added through VS2015 "Add Service Reference". I have also "attached" to the server and the server keeps running and prints in the console before and after logs (to confirm that everything is ok).
What am I missing? What configuration and where do I need to change so that the task can run for more than 1 minute and 40 seconds?
CODE:
Example of Server Pseudo-Code:
Interface File:
[ServiceContract(Namespace="http://.....")]
interface ICom {
[OperationContract]
int call(int val);
}
Service.cs
public ServiceHost serviceHost = null;
public BlaBlaWindowsService()
{
ServiceName = "BlaBlaWindowsService";
}
public static void Main()
{
ServiceBase.Run(new BlaBlaWindowsService());
}
protected override void OnStart(string[] args)
{
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(BlaBlaService));
serviceHost.Open();
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "BlaBlaWindowsService";
Installers.Add(process);
Installers.Add(service);
}
}
BlaBlaService.cs
class TPAService : ITPAComunication {
public int call(int val) {
System.Threading.Thread.Sleep(200000)
return 0;
}
}
App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<binding name="ServiceTimeout" closeTimeout="00:10:00" receiveTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00"/>
</bindings>
<services>
<service name="BlaBla.Service.Service"
behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/BlaBla/service"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="ServiceTimeout"
contract="BlaBla.Service.ICom" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Example of App pseudo-code:
System.ServiceModel.EndpointAddress epa = new System.ServiceModel.EndpointAddress("http://localhost:8000/blabla/service");
System.ServiceModel.BasicHttpBinding bhb = new System.ServiceModel.BasicHttpBinding();
Timespan t = new TimeSpan(0, 10, 0);
bhb.SendTimeout = t; bhb.ReceiveTimeout =t; bhb.OpenTimeout = t; bhb.CloseTimeout = t;
Blabla.ComunicationClient com = new Blabla.ComunicationClient(bhb, epa);
var obj = await com.callAsync(int val);
return obj;
UPDATE #1
This situation only happens in UWP. I have created a similar WinForms project and everything works as expected. This means that it is probably something related to UWP.
After several tries, manipulating different config files, I have not found a solution regarding how to remove the timeout limitation of 100 seconds. To solve this specific problem, I implemented a counter-measure.
What I have found during my tries was:
How I solved this?
After chatting at C# SO channel, @Squiggle suggested a polling approach and that is what I implemented and tested successfully.
These are the steps I took:
There are other possible solutions such as sockets, which I have not tried, that could work.
* If all the requests take more than 100 seconds, I suggest using the polling approach from the beginning of the requests, instead of waiting for the try/catch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With