【问题标题】:Exception during dictionary initialization字典初始化期间的异常
【发布时间】:2013-02-26 17:40:58
【问题描述】:

我在尝试从 WCF 服务调用方法时遇到类型初始化错误。

“X.Y.Z.AuditService”的类型初始化程序引发了异常。

但是,我在代码中看不到任何会导致异常的内容。

public enum AuditProcessType
{
    Facility,
    Patient,
    Report,
}


[ServiceBehavior(Name = "AuditService",
    Namespace = "http://xyz/services/2008/08",
    InstanceContextMode = InstanceContextMode.PerSession,
    ConcurrencyMode = ConcurrencyMode.Single)]
public class AuditService : IAuditServiceContract
{
    private static Dictionary<AuditProcessType, Func<IAuditor>> auditServiceFactories;

    static AuditService()
    {
        auditServiceFactories = new Dictionary<AuditProcessType, Func<IAuditor>>()
        {
            { AuditProcessType.Facility, () => Auditor<Facility>.Instance },
            { AuditProcessType.Patient, () => Auditor<Patient>.Instance },
            { AuditProcessType.Report, () => Auditor<Report>.Instance },
        };
    }

    // ...

    private static IAuditor GetAuditor(AuditProcessType process)
    {
        Func<IAuditor> factory;
        if (!auditServiceFactories.TryGetValue(process, out factory) || factory == null)
        {
            throw new ArgumentException(..., "process");
        }

        IAuditor auditor = null;
        try
        {
            auditor = factory();
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(..., ex);
        }

        if (auditor == null)
        {
            throw new InvalidOperationException(...);
        }

        return auditor;
    }
}

public class Auditor<T> : IAuditor
{
    private static Auditor<T> _instance = new Auditor<T>();

    public static Auditor<T> Instance
    {
        get
        {
            return _instance;
        }
    }

    private Auditor()
    {
    }

    // ...
}

我的日志框架没有显示任何内部异常细节,所以我无法获得比这更多的信息。无论我尝试了什么,我似乎都无法让 VS 调试器在类型初始化程序中停止。不过,我看不出这段代码是如何引发异常的。我的代码本身除了初始化工厂字典什么都不做,它甚至不调用AuditService&lt;T&gt;.Instance。还有什么可能导致这种情况?

【问题讨论】:

  • 有关详细信息,您可以将“Auditor.Instance”属性的代码放入try catch块中。还可以在调试器中切换一些属性可能有帮助。
  • AuditService,你也有非静态构造函数吗?
  • @DanielHilgarth 不,我没有。

标签: c# wcf exception-handling


【解决方案1】:

为了使类型初始化程序失败,它必须执行一些代码 - 并且该代码必须失败。查看您发布的内容,唯一的可执行代码在这里:

{ ... , () => Auditor<Facility>.Instance },
{ ... , () => Auditor<Patient>.Instance },
{ ... , () => Auditor<Report>.Instance },

将您的 lambda 表达式更改为

() => { 
    try { return Auditor<Facility>.Instance;  } 
        catch (Exception ex) 
        { System.Diagnostics.WriteLine(ex.Message); } 
}

看看这是否没有捕捉到某种错误。

【讨论】:

  • 没有执行 lambdas。
  • 是的,嗯。我想知道,他是否实例化了一个空字典?
  • 我的代码创建了一个工厂方法字典(作为 lambda 表达式)。我在我的服务方法中按需创建每个IAuditor。实际上,为了安全起见,我确实将每个工厂方法包装在一个 try-catch 中,但这是在一个名为 GetAuditor 的单独方法中完成的。我在问题中包含了该方法的实现以供参考。
  • 如果您指的是.svc 文件,这很简单:&lt;%@ServiceHost language="c#" Debug="true" Service="X.Y.Z.AuditService" %&gt;
  • 什么时候使用GetAuditor?另外,您的 AuditService 类中还有其他静态字段吗?
【解决方案2】:

我将此归结为程序集加载错误。 IAuditor 是在与AuditService 分开的程序集中定义的,并且由于部署期间的问题,IAuditor 接口的程序集正确地未包含在应用程序的 bin 目录中。它在类型初始化期间给了我一个错误,因为那是发生程序集加载的地方。

【讨论】:

    猜你喜欢
    • 2023-01-19
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    相关资源
    最近更新 更多