我有一个应用程序(UWP - Win10)和一个Windows服务。
该服务在后台运行,它们都是用C#开发的。 " callAsync"是服务的方法。我正在等待在客户端上调用它。
var obj = await callAsync(10);
问题是: 如果此调用时间少于1分40秒(100秒),那么一切正常。但是如果它需要超过1分40秒,那么将发生异常" TaskCanceledException:任务被取消"。
我搜索了SO和网络,但仍然找不到任何关于如何解决此问题的指示"超时"问题。我添加了所有"打开/关闭/接收/发送"应用程序和服务app.config上的超时标志,尽管在这种情况下抛出的异常是不同的。
如果我在客户端尝试简单的延迟:
await Task.delay(200000);
它运作正常。
此服务是通过VS2015"添加服务参考"添加的。我还附上了#34;到服务器和服务器继续运行并在日志之前和之后在控制台中打印(以确认一切正常)。
我错过了什么?我需要更改哪些配置以及在哪里进行更改,以便任务可以运行超过1分40秒?
CODE:
服务器伪代码示例:
接口文件:
[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文件:
<?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>
App伪代码示例:
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;
更新#1
这种情况只发生在UWP中。我创建了一个类似的WinForms项目,一切都按预期工作。这意味着它可能与UWP有关。
答案 0 :(得分:2)
经过几次尝试,操作不同的配置文件,我还没有找到关于如何删除100秒的超时限制的解决方案。为了解决这个具体问题,我实施了一项对策。
我在尝试期间发现的是:
我是如何解决这个问题的?
在C#SO频道聊天后,@ Squiggle提出了一种投票方法,这就是我成功实施和测试的方法。
这是我采取的步骤:
还有其他可能的解决方案,例如套接字,我还没试过,可以使用。
* 如果所有请求都需要超过100秒,我建议从请求开头使用轮询方法,而不是等待try / catch。
答案 1 :(得分:0)
我确定不确定 - 但可能更好地使用Task.WhenAll而不是等待?