7

无法理解为什么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;
        }
    }
}
4

1 回答 1

6

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

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

于 2012-12-25T14:18:32.610 回答