我正在开发一个 WCF 客户端/服务器应用程序,客户端通过将调用包装在其中Task.Factory.StartNew
并在 WCF 调用返回时使用延续调用用户提供的委托来异步调用服务器。服务器操作在向客户端返回响应之前执行(除其他外)一些串行 I/O。该服务还利用 BlockingCollection 将这些请求排入队列,确保它们一次执行一个,以避免串行端口争用。就目前而言,该应用程序运行得非常好,即使客户端快速连续地向服务器发出大量请求。
现在,该应用程序还可以配置为以“直接”模式运行,其中客户端直接引用服务器端程序集(出于性能原因,如果客户端和服务器位于同一台 PC 上)。在这种情况下,客户端使用服务类的实例(而不是 ChannelFactory 创建的代理)并使用相同的异步Task.Factory.StartNew
帮助器直接调用其操作方法。
在这种“直接”模式下,我发现服务器端执行似乎运行缓慢(它错过了串行端口数据),就好像它以某种方式被中断了一样。我可以通过将客户端任务更改为使用来“修复”它TaskCreationOptions.LongRunning
。不幸的是,这会在“WCF 模式”下破坏应用程序,这似乎会遇到同样的缓慢问题。
现在,我可以简单地包含 TaskCreationOptions(或不包含),具体取决于应用程序使用的“模式”,但我想首先了解为什么会发生这种情况。有任何想法吗?
编辑:当客户端一个接一个地向服务器发送十几个请求时,我注意到应用程序启动期间的问题,在for
环形。在此之后,客户端每半秒轮询一次服务器 - 这不受问题的影响,其他两个同时运行客户端和服务器端的线程计时器也不受影响(其中一个每 65 毫秒触发一次!)。我看到一篇文章说线程池将创建新线程,直到达到最小线程数,之后它将创建的线程数限制为每 500 毫秒一个。这与我的问题的症状相匹配,因为我看到大约每半秒出现一次缓慢。我将重构我的客户端代码以避免快速连续多次访问服务器,这是一种耻辱。我真的很想一个接一个地触发所有这些请求,然后在服务器处理完回调委托后处理结果。但是有了这个线程池“