WCF服务方法中单例模式的问题

Joh*_*ell 8 .net c# wcf singleton web-services

我将继续前言,并说:我对WCF有些新意.

我正在研究一个服务器端例程,它负责执行大量的业务逻辑.它可以通过WCF从客户端访问.

我的主要WCF方法调用其他几个私有方法.我决定使用包含所有这些"查找数据"的名为DataProvider的类的单例实例,而不是传递每个私有方法的业务逻辑所需的所有"查找数据".

在例程结束时,我"释放"DataProvider的查找数据,以便下次执行例程时,将使用最新的查找数据.

所以,这是一个简化的例子:

 public void Generate()
 {
      try
      {
           //populate singleton DataProvider with it's lookup data...
           DataProvider.Instance.LoadLookupData();

           //do business logic...
      }
      finally
      {
           //release provider's lookup data...
           DataProvider.Release();
      }
 }
Run Code Online (Sandbox Code Playgroud)

这很有效,直到我有两个不同的客户端在同一时间(或接近)执行该方法.出现问题是因为它们共享相同的单例实例,并且首先完成的任务将在另一个完成之前释放DataProvider.

所以...

我有什么选择?

我想避免传递所有的查找数据,因此单例模式(或某些衍生物)似乎是一个不错的选择.我还需要能够支持同时调用该方法的多个客户端.

我相信WCF服务配置为"Per-Call".我不确定是否有办法配置WCF服务,以便在服务调用之间不共享静态内存.

任何帮助,将不胜感激.

Vla*_*den 8

默认情况下,WCF使用"Per-Call",这意味着为每个客户端的调用创建了WCF服务的新实例.既然你已经实现了单例,即使创建了WCF的新实例,它仍然会调用你的单例.

如果您想创建为每个调用创建的查找(就像您现在所做的那样),则不应将其作为单例执行.这样调用方法的每个客户端都会有新的查找实例,我认为这是你的意图.

但是,如果您的查找没有快速更改,我建议在所有调用之间共享它,这将提高WCF服务的性能.您需要将WCF服务声明为

InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple  
Run Code Online (Sandbox Code Playgroud)

这样做是由WCF 自动为您创建Singleton,因此您不必自己动手,其次它将支持> 1并发用户(ConcurrencyMode.Multiple).

现在,如果您的查找正在发生变化,并且需要在一段时间后重新加载,我仍然建议您使用

InstanceContextMode = InstanceContextMode.Single 
ConcurrencyMode = ConcurrencyMode.Multiple
Run Code Online (Sandbox Code Playgroud)

但是在你的代码里面缓存它然后在特定时间或相对时间(1小时)使你的缓存失效.

以下是一些可能对您有所帮助的链接: 3种方式进行WCF实例管理(每次调用,每次会话和单次)

希望这会有所帮助.

  • 我在谈论更多关于在WCF服务的方法中处理同步的问题,因为`ConcurrencyMode.Multiple`意味着可以有多个线程同时执行相同的方法.通过per-call,每个请求都有一个实例,因此当您处理静态变量时,多线程和同步只会成为问题. (2认同)