11

我正在用 C# 编写 WCF 服务。最初,我的实现有一个静态构造函数来执行一些一次性初始化,但是正在完成的一些初始化可能(暂时)失败。

即使第一次(失败的)尝试引发了异常,静态构造函数似乎只被调用一次?任何后续实例化我的类的尝试都将立即失败,并且TypeInitializationException没有实际执行代码。

C# 语言规范规定,静态构造函数最多调用一次,但基本上这会在其中产生一个异常,即使您捕获它,您也无法从中恢复?

我在这里错过了什么吗?我想我应该将任何远程危险的东西移到服务的实例构造函数中,并手动检查类初始化是否已经成功完成?

4

3 回答 3

4

这里的教训很简单:不要在静态构造函数中做任何可能合理失败的事情。

于 2009-08-25T14:05:31.133 回答
4

因此,您可以将关键部分包装在 try/catch 中,至少这意味着该类型不会初始化失败,但如果初始化代码非常关键,那么这种行为实际上是好的——该类型在未初始化的情况下不可用状态。

另一种选择是将其作为单例进行 - 每次您尝试获取实例时,您都可以正确创建类型,直到您成功,即使它第一次失败。

如果 Instance 第一次(或第二次等)返回 null,您仍然需要对调用者进行一些错误处理。

编辑:如果你不想要一个单例,那么只需让你的实例构造函数初始化静态部分

例如

private object _lock = new object()
private bool _initialized;

public T()
{
   lock(_lock)
   {
      if(!_initialized)
      {
         try
         {
           //Do static stuff here
         }
         catch(Exception ex_)
         {
           //Handle exception
         }
      } 
   }
}
于 2009-08-25T14:07:14.857 回答
1

我过去使用的解决方法是创建一个 Singleton。当且仅当失败意味着整个应用程序无法运行时,才使静态构造函数失败。

于 2009-08-25T14:08:18.663 回答