我试图了解WCF的实例是如何工作的。我有一个WCF服务,InstanceContextMode设置为PerCall(因此,每个客户端的每个调用都将创建一个新实例),并且ConcurrencyMode设置为Single(因此服务实例一次只执行一次或不执行任何操作调用)。 / p>
因此,据我所知,当客户端连接时,会创建一个新实例。 但是当客户离开服务时会发生什么。实例是否会死。我问的原因是因为我需要在服务中实现ConcurrentQueue。因此,客户端将连接到服务并放入要处理的大量数据,然后离开服务。工人们将排队等候。工作完成后,我需要销毁实例。
答案 0 :(得分:3)
基本上,从Juval Lowy采用的“WCF大师班级”学习,每次呼叫激活是需要扩展的服务的首选,即需要处理大量并发请求。
为什么?
通过每次调用,每个传入请求(最多可配置限制)都会获得自己的,新鲜的,孤立的服务类实例来处理请求。实例化服务类(普通的旧.NET类)并不是一个很大的开销 - 而且WCF运行时可以轻松地管理10个,20个,50个并发运行的服务实例(如果您的服务器硬件可以处理它)。由于每个请求都有自己的服务实例,因此该实例一次只处理一个线程 - 而且编程和维护非常简单,不需要繁琐的锁和使其成为线程安全的东西。
使用单件服务(InstanceContextMode=Single
)要么是一个可怕的瓶颈(如果你有ConcurrencyMode=Single
- 那么每个请求都是序列化的,一个接一个地处理),或者如果你想要体面的性能,你需要ConcurrencyMode=Multiple
,但这意味着你有一个服务类实例处理多个并发线程 - 在这种情况下,你作为该服务类的程序员必须100%确保所有代码,所有对变量的访问权限等100%是线程安全的 - 这确实是一项非常重要的任务!只有极少数程序员真正掌握了这种黑色艺术。
在我看来,与为多线程单例WCF服务类创建完全线程安全实现的要求相比,在每次调用场景中创建服务类实例的开销是无效的。
因此,在具有中央队列的具体示例中,我会:
创建一个简单的WCF每次调用服务,该服务从您的客户端调用,并且只将消息放入队列中(以适当的方式,例如可能转换传入的数据或其他内容)。这是一个快速的任务,没什么大不了的,没有任何繁重的处理 - 因此你的服务类将非常简单,非常直接,没有大的开销来创建那些类实例
创建一个工作服务(Windows NT服务或其他东西),然后读取队列并进行处理 - 这基本上完全独立于任何WCF代码 - 这只是做出队列和处理
< / LI>所以我所说的是:尝试将服务调用(提供数据)与必须构建队列分开并进行大量处理密集型计算 - 分担责任:WCF服务应该只接收数据并将其放入队列或数据库然后完成 - 而第二个独立的过程应该进行处理/繁重。这使您的WCF服务精益求精
答案 1 :(得分:0)
是的,每次调用意味着,每个连接都会有一个新服务,一旦你将实例上下文模式设置为percall并将ConcurrencyMode设置为single,它将是每个调用的单线程。当客户离开时,完成该工作,您的实例将处置。在这种情况下,你想要多次创建你的并发队列,据我所知,你需要一个并发队列吗?那是对的吗?
我建议你使用IntanceContextMode = Single和ConcurrencyMode来处理Mutli线程。这样可以更好地扩展。如果使用此方案,您将拥有一个并发队列,并且可以将所有项目存储在该队列中。
一个小注,ConcurrentQueue,有一个bug,你应该知道,检查bug数据库。