2

我试图了解 WCF 的实例是如何工作的。我有一个 WCF 服务,其 InstanceContextMode 设置为 PerCall(因此对于每个客户端的每次调用,都会创建一个新实例)和 ConcurrencyMode 设置为 Single(因此服务实例一次只执行一个或不执行操作调用)。

因此,据我所知,当客户端连接时,会创建一个新实例。但是当客户离开服务时会发生什么。实例是否死亡。我问的原因是因为我需要在服务中实现一个 ConcurrentQueue。因此,客户端将连接到服务并放置要处理的大量数据,然后离开服务。工人将排队工作。工作完成后,我需要销毁实例。

4

2 回答 2

3

基本上,从 Juval Lowy 的“WCF Master Class”中学习,每次调用激活是需要扩展的服务的首选,即需要处理大量并发请求的服务。

为什么?

通过每次调用,每个传入请求(最多可配置限制)都会获得自己的、新鲜的、隔离的服务类实例来处理请求。实例化一个服务类(一个普通的旧 .NET 类)并不是一个很大的开销 - WCF 运行时可以轻松管理 10、20、50 个并发运行的服务实例(如果您的服务器硬件可以处理它)。由于每个请求都有自己的服务实例,该实例一次只处理一个线程——而且它完全易于编程和维护,不需要繁琐的锁和使其成为线程安全的东西。

InstanceContextMode=Single使用单例服务ConcurrencyMode=SingleConcurrencyMode=Multiple多个并发线程 - 在这种情况下,作为该服务类的程序员,您必须 100% 确保您的所有代码、对变量的所有访问等都是 100% 线程安全的 - 这确实是一项艰巨的任务!只有极少数程序员真正掌握了这门黑魔法。

在我看来,与为多线程单例 WCF 服务类创建完全线程安全实现的要求相比,在每次调用场景中创建服务类实例的开销微不足道。

因此,在您使用中央队列的具体示例中,我会:

  • 创建一个简单的 WCF 每次调用服务,该服务从您的客户端调用,并且仅将消息放入队列(以适当的方式,例如可能转换传入数据或其他内容)。这是一项快速的任务,没什么大不了的,没有任何类型的繁重处理 - 因此您的服务类将非常简单,非常简单,根本不需要创建这些类实例的大开销

  • 创建一个工作服务(Windows NT 服务或其他东西),然后读取队列并进行处理 - 这基本上完全独立于任何 WCF 代码 - 这只是进行出队和处理

所以我要说的是:尝试将服务调用(传递数据)与必须建立队列并进行大型和处理密集型计算分开 - 划分职责:WCF 服务应该只接收数据和将它放入队列或数据库中,然后完成它 - 第二个单独的进程应该进行处理/繁重的工作。这使您的 WCF 服务保持精简

于 2011-11-23T20:44:54.547 回答
0

是的,每次调用意味着,每个连接都将拥有一个新的服务实例,一旦将实例上下文模式设置为 percall 并将 ConcurrencyMode 设置为 single,每次调用它将是单线程的。当客户离开并完成工作时,您的实例将被处置。在这种情况下,您要小心不要多次创建并发队列,据我所知,您需要一个并发队列吗?那是对的吗?

我建议您使用 IntanceContextMode=Single 和 ConcurrencyMode 来进行 Mutli 线程。这可以更好地扩展。如果您使用此方案,您将拥有一个并发队列,并且您可以将所有项目存储在该队列中。

一个小笔记,ConcurrentQueue,有一个错误,你应该知道,检查错误数据库。

于 2011-11-23T18:52:22.523 回答