多线程的陌生感

时间:2012-08-31 14:22:24

标签: c# .net multithreading wcf task-parallel-library

我正在开发一个WCF客户端/服务器应用程序,并且客户端通过在Task.Factory.StartNew中包装调用并使用continuation从WCF调用返回时调用用户提供的委托来异步调用服务器。在将响应返回给客户端之前,服务器操作执行(除其他之外)某些串行I / O.该服务还利用BlockingCollection将这些请求排入队列,确保一次执行一个请求以避免串行端口争用。就目前而言,即使客户端快速连续向服务器发出大量请求,该应用程序也能完美运行。

现在,应用程序还可以配置为以“直接”模式运行,其中客户端直接引用服务器端程序集(出于性能原因,如果客户端和服务器位于同一台PC上)。在这种情况下,客户端使用服务类的实例(而不是ChannelFactory创建的代理)并使用相同的异步Task.Factory.StartNew帮助程序直接调用其操作方法。

在这种“直接”模式下,我发现服务器端执行似乎运行缓慢(它错过了串口数据),好像它在某种程度上被中断了。我可以通过将客户端任务更改为使用TaskCreationOptions.LongRunning来“修复”它。不幸的是,当处于“WCF模式”时,这会破坏应用程序,这似乎会遇到相同的缓慢问题。

现在,我可以简单地包含TaskCreationOptions(或不包括),具体取决于应用程序使用的“模式”,但我想了解为什么会发生这种情况。有什么想法吗?

修改: 我发现在app启动期间,当客户端在for循环中一个接一个地向服务器发送十二个请求时,问题就出现了。在此之后,客户端每隔半秒轮询一次服务器 - 这不受问题的影响,另外两个线程计时器也不会同时运行客户端和服务器端(其中一个每隔65毫秒触发一次!)。我遇到一篇文章,说明线程池将创建新线程,直到达到最小线程数,之后它将创建的线程数限制为每500毫秒一个。这符合我的问题的症状,因为我看到大约每半秒发生一次慢速。 我将重构我的客户端代码,以避免快速连续多次击中服务器,这是一种耻辱。我真的想一个接一个地关闭所有这些请求,然后在服务器处理完回调代理后处理结果。但是使用这个线程池“功能”似乎我不能这样做。

2 个答案:

答案 0 :(得分:1)

如果切换到LongRunning会解析它,这意味着当未设置LongRunning时,任务框架选择使用线程池,或者甚至根本不使用单独的线程。

答案 1 :(得分:0)

您可以运行一些性能工具或附加计时器以找出瓶颈所在。或者,在命名管道上使用WCF模式。 (http://msdn.microsoft.com/en-us/library/ms733769.aspx)