2011-11-23 63 views
2

我想了解WCF实例如何工作。我有一个将InstanceContextMode设置为PerCall的WCF服务(因此每个客户端的每次调用都将创建一个新实例),并将ConcurrencyMode设置为Single(因此服务实例一次仅执行一次操作调用或不执行任何操作调用)。WCF实例如何工作

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

回答

3

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

为什么?

通过每次调用,每个传入请求(达到可配置的限制)都会获得自己的,新鲜的,孤立的服务类实例来处理请求。实例化一个服务类(一个普通的旧.NET类)并不是一个很大的开销 - 并且WCF运行时可以轻松地管理10,20,50个并发运行的服务实例(如果您的服务器硬件可以处理它的话)。由于每个请求都有自己的服务实例,因此该实例一次只能处理一个线程 - 并且编程和维护都非常容易,不需要繁琐的锁和其他线程安全所需的东西。

使用单独服务(InstanceContextMode=Single)可以是一个可怕的瓶颈(如果你有ConcurrencyMode=Single - 那么每个请求被序列化,处理一个又一个的),或者如果你想不俗的表现,你需要ConcurrencyMode=Multiple,但是这意味着你有处理多个并发线程的服务类的一个实例 - 在这种情况下,作为该服务类的程序员,您必须确保所有代码,对变量等的所有访问都是100%线程安全的 - 这就是的确是一项任务!只有极少数的程序员真的掌握了这种黑色艺术。

在我看来,在每个调用场景中创建服务类实例的开销与为多线程单例WCF服务类创建完全线程安全的实现的要求相比没有任何意义。

因此,在你与中央队列具体的例子,我想:

  • 创建一个会从你的客户称为一个简单的WCF每次通话服务,只有邮件放入队列(以适当的方式,例如可能转换传入的数据或其他东西)。这是一个快速的任务,没有什么大不了的,没有任何重要的处理 - 因此你的服务类将非常简单,非常直接,根本没有大的开销来创建这些类实例

  • 创建一个工人服务Windows NT服务或某事),其然后读取队列,并做处理 - 这基本上是完全独立于任何WCF代码 - 这只是做出列和处理

所以,我要说的是:尽量将服务调用(即提供数据)与建立队列分开,并执行大量且处理密集型计算 - 将职责分开:WCF服务应只接收数据并将p将它放入队列或数据库中,然后完成它 - 另一个单独的过程应该处理/繁重。这使您的WCF服务精益'n'mean

+0

你将需要一个单例来实现队列,然后prolly'懒惰'。 – DarthVader

0

是的,每次调用意味着每次连接都会有一个新服务,一旦将实例上下文模式设置为percall并且ConcurrencyMode设置为单次,则每个调用都将使用单线程。当客户离开时,完成这个工作,你的实例将被处置。在这种情况下,您希望不会多次创建并发队列,就我所能想象的那样,您将需要一个并发队列?那是对的吗?

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

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

+0

感谢您的答复。那么我没有打算使用InstanceContextMode = Single with ConcurrencyContextMode = Multiple,因为在服务中还有其他数据合同不是线程安全的。所以我猜如果我只使用一个普通的队列,在这个队列中数据将被推入,并且在加载队列之后将启动一个工作线程将适用于我。我只需要确保所有线程完成,这将允许实例处置。 – Amitesh

+0

@marc_s不同意单个上下文模式和多线程的原因是什么?每个呼叫上下文的创建,处理和维护都非常昂贵?特别是有一个集中的队列,如何将其整合到每个呼叫模式? – DarthVader

+1

@marc_s http://msdn.microsoft.com/en-us/magazine/cc163590.aspx#S1,请参阅每次调用方法,每次需要创建服务时,本身已经非常昂贵。这篇文章指出这种方法不能很好地扩展。在一个上下文中,你创建了一个服务实例,每个调用获得一个新的线程,它与httpd非常相似,而每个调用与perl-cgi在几天内用来恢复的方式非常相似。使用并发集合不会使多线程变得困难。 – DarthVader