【问题标题】:How to make a call to WCF webservice with more than one client at the same time (in parallel)如何同时使用多个客户端(并行)调用 WCF Web 服务
【发布时间】:2012-06-21 21:36:47
【问题描述】:

我有一个 c# WCF Web 服务,它是一个服务器,我有 2 个客户端,一个是 java 客户端,另一个是 c++ 客户端。我希望两个客户端同时运行。我有但无法弄清楚的情况是:

我的 java 客户端将调用 WCF Web 服务,处理时间可能需要 10 分钟左右,同时我希望我的 c++ 客户端调用 Web 服务并获取响应。但是现在我只能在处理 java 客户端请求时使用 c++ 客户端调用 Web 服务。在 Java 客户端请求完成之前,我没有收到 C++ 客户端请求的响应。

谁能建议我如何使这项工作并行。提前致谢。

【问题讨论】:

  • 我假设您正在寻找并发性。我建议您阅读有关 WCF 服务实例化和服务限制的更多信息,因为这些是 WCF 并发的主要贡献。

标签: c# wcf parallel-processing httpwebrequest


【解决方案1】:

任何“正常”的 WCF 服务都绝对可以在任何给定时间处理多个客户端请求。

这完全取决于您对InstanceContextMode 的设置:

  • PerSession 意味着,每个会话都会获取服务类的副本来处理多个请求(来自同一个客户端)

  • PerCall 意味着,每个请求都会获得服务类的新副本来处理请求(并在处理调用后再次释放)

  • Single 表示您有一个单例 - 只是您的服务类的一个副本。

如果你有一个单例 - 你需要问自己:为什么?默认情况下,PerCall 是推荐的设置,它应该很容易同时支持很多请求。

请参阅Understanding Instance Context Mode 以获得更详尽的说明。

【讨论】:

  • 知道什么是 InstanceContextMode 的默认值吗?它可以接受的默认客户端请求的数量是多少?
  • @krishna555:这取决于所使用的绑定 - 可能是 PerSessionPerCall
【解决方案2】:

使用

[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple )]

归因于您的服务类。更多关于这个的例子在这里:

http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and

【讨论】:

  • 如果您的实例上下文模式为PerCallPerSession,这不需要,并且可能会使服务类的编程更具挑战性(一切都必须是完全线程安全)
【解决方案3】:

这是您的问题的外围,但您是否考虑过来自需要 10 分钟以上才能返回的方法的异步回调,然后让进程在单独的线程中运行?让服务调用同步等待 10 分钟并不是一个很好的做法,并且可能会解决您的问题,尽管该服务应该允许同时允许多个调用者(我们的 WCF 服务需要数千个同时请求)。

当您调用 WCF 时,您可以选择同步或异步调用它。同步调用等待响应在同一操作中发送回调用者。在调用者中,它看起来像“myresult = svc.DoSomething()”。使用异步调用,调用者为服务提供一个函数,以便在服务完成时调用,但不等待响应。调用者在等待响应时不会阻塞并继续其业务。

您的回调将采用 DoSomethingCompletedEventArgs: void myCallback(对象发送者,DoSomethingCompletedEventArgs e) { var myResult = e.Result; //然后使用之前的结果。 }

您像事件处理程序一样注册回调函数: svc.DoSomethingCompleted+=myCallback; 然后 svc.DoSomethingAsync()。请注意,该语句中没有返回值;该服务将在完成时执行 myCallBack 并传递结果。 (来自 Silverlight 的所有 WCF 调用都必须是异步的,但对于其他客户端,此限制不存在)。

这是一篇 codeproject 文章,详细演示了一种略有不同的方式。 http://www.codeproject.com/Articles/91528/How-to-Call-WCF-Services-Synchronously-and-Asynchr

这可以防止客户端在 10 多分钟的过程中阻塞,但不会真正改变服务本身的运行方式。

现在我提到的第二部分是在服务内部的一个单独线程中启动 10 多分钟的进程。服务方法本身应该很薄,只是调用其他库中的功能。需要很长时间的函数最好在它们自己的线程中调用(比如一个后台工作线程,当它完成时你会在服务端注册一个回调),并且有某种持久性系统来跟踪它们的进度和任何需要返回给客户的结果。如果是我,我会在数据库中注册该进程的请求,然后在完成后更新该数据库。然后,客户端将定期启动一个简单的轮询,以查看该过程是否已完成并获得任何结果。您也许可以设置双工绑定,以便在进程自动完成时收到通知,但老实说,我已经有几年没有做过双工绑定了,所以我不记得它是如何工作的了。

这些话题实在是太大了,我无法在此深入探讨。我建议使用 BackgroundWorker 研究多线程操作。

【讨论】:

  • 它没有完全理解你关于异步回调的问题(你能解释一下吗?)。正如您所说,默认服务应该一次允许多个呼叫者,您知道它可以允许多少个呼叫者(固定数量)。
  • 我没有空间将 cmets 放在这里,所以我将编辑上面的“答案”。
  • 您在上面提供的描述是完整的帮助,我编写了另一个 c++ 客户端,它调用相同的 Web 服务并通知用户主进程正在运行的步骤,以便用户知道程序是仍在运行并处于特定位置。感谢您的建议。
猜你喜欢
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 2014-09-04
  • 2010-10-15
  • 1970-01-01
相关资源
最近更新 更多