为PerSession WCF服务调用两次的静态构造函数

时间:2012-12-25 14:09:17

标签: c# multithreading wcf silverlight .net-4.0

不能udnerstand为什么PerSession / WCF服务的类型构造函数调用了两次。 ConcurrencyModeMultiple。 只需启动五个同时进行相同WCF服务方法调用的客户端,在日志中我看到static构造函数被调用两次,第一次和第二次3秒后再调用另一个ProcessId/ThreadId。在构造函数本身和WCF跟踪日志中都没有例外。 每个日志的构造函数执行时间约为10毫秒。这导致所有静态字段不在假设的所有服务实例之间共享,并且在5个客户端连接的情况下,我有5个服务和两个不同的静态上下文,因此onse静态字段的更改不会反映在所有服务中。

由于我依赖于在多个服务实例之间共享的一些静态缓存,因此这个问题会引起很多困惑。

服务托管在IIS。没有IIS重新启动,AppPool会在此时间间隔内重复使用。

[AspNetCompatibilityRequirements(RequirementsMode =
  AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(
  InstanceContextMode = InstanceContextMode.PerSession, 
  IncludeExceptionDetailInFaults = true, 
  ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WcfService
{ 
    private static readonly ILog logger;
    private static volatile bool typeInitialized;

    static WcfService()
    {
        try
        {
            // Here is typeInitialized is false in both calls
            logger = LogManager.GetLogger("LogName");

            logger.InfoFormat("[PID:{0}] [THID:{1}] BEGIN Static constructor",
               Process.GetCurrentProcess().Id,
               Thread.CurrentThread.ManagedThreadId);
        }
        catch (Exception exception)
        {
           logger.Error("error on type construction stage", exception);
        }
        finally
        {
            logger.InfoFormat("[PID:{0}] [THID:{1}] END Static constructor",
               Process.GetCurrentProcess().Id,
               Thread.CurrentThread.ManagedThreadId);               
           typeInitialized = true;
        }
    }
}

1 个答案:

答案 0 :(得分:6)

假设您使用IIS托管服务,这是正常行为,除非您明确将进程配置为仅允许单个AppDomain被启动。

如果查看正在运行的进程列表,您会发现日志中的每个进程ID都与托管单独应用程序域的w3wp.exe副本相对应。