【问题标题】:Multithreading strangeness多线程奇怪
【发布时间】:2012-08-31 14:22:24
【问题描述】:

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

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

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

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

编辑: 我注意到应用程序启动期间的问题,当客户端在for 循环中一个接一个地向服务器发送十几个请求时。在此之后,客户端每半秒轮询一次服务器 - 这不受问题的影响,其他两个同时运行客户端和服务器端的线程计时器也不受此影响(其中一个每 65 毫秒触发一次!)。我看到一篇文章说线程池将创建新线程,直到达到最小线程数,之后它将创建的线程数限制为每 500 毫秒一个。这与我的问题的症状相匹配,因为我看到大约每半秒出现一次缓慢。 我将重构我的客户端代码以避免快速连续多次访问服务器,这是一种耻辱。我真的很想一个接一个地触发所有这些请求,然后在服务器处理完回调委托后处理结果。但是有了这个线程池“功能”,我似乎无法做到这一点。

【问题讨论】:

  • 首先想到的疯狂猜测是,直接端的代理类正在幕后做一些事情——目前还不知道——直接实例版本不是。这就是我开始寻找的地方,至少......
  • 您可以在您的客户端/服务器之间共享某个对象的实例吗?在 WCF 模式下,您不会共享实例,在直接模式下,您可能会共享实例,您可能对此有疑问?
  • @jasper 链接是通过“外观”项目建立的——客户端直接引用此项目,但没有直接引用服务器端程序集。
  • 您的更新还解释了 LongRunning 解决它的原因,因为它不再使用线程池

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


【解决方案1】:

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

【讨论】:

  • 这很奇怪,因为服务操作只是将请求排入 BlockingCollection 并很快返回。令人费解的是为什么我必须指定 LongRunning 才能让它工作。服务器端使用了许多后台线程/任务,因此客户端异步任务包装器的东西可能会以某种方式干扰。
  • @Andrew 我和你一样有兴趣看看问题的最终根源是什么,但是如果实际的服务操作确实完成得这么快,那么客户端 使用任务启动它?如果客户端直接在其当前线程上执行会发生什么?
  • @shambulator 如果我只是同步调用操作,一切正常。我可能已经非常专注于尝试使用现有的异步代码来解决这个问题,以至于我没想到这是一个解决方案。我想唯一的问题是,如果该服务在未来被扩展以包括那些不那么短暂的操作。也许这就是那些“当我来到它时我会越过那座桥”的事情之一......
  • @shambulator 仅供参考,请参阅上面的编辑以获取有关问题和可能原因的更多信息。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-07
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    相关资源
    最近更新 更多