类型初始值设定项(静态构造函数)异常处理

发布于 2024-08-02 15:34:38 字数 304 浏览 1 评论 0原文

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

看来静态构造函数只被调用一次,即使第一次(失败)尝试抛出异常?任何后续实例化我的类的尝试都将立即失败,并出现 TypeInitializationException,而不会实际执行代码。

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

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

I'm writing a WCF service in C#. Initially my implementation had a static constructor to do some one-time initialization, but some of the initialization that is being done might (temporarily) fail.

It appears that static constructors are only called once, even if the first (failed) attempt threw an exception? Any subsequent attempts to instantiate my class will immediately fail with a TypeInitializationException without the code actually being executed.

The C# language specification states that a static constructor is called at most once, but basically this makes an exception in there an error that you cannot ever recover from, even if you catch it?

Am I missing something here? I suppose I should move anything remotely dangerous to the service's instance constructor and manually check whether or not the class initialization was already succesfully completed earlier?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡水深流 2024-08-09 15:34:38

因此,您可以将关键部分包装在 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
         }
      } 
   }
}

So you could wrap the critical parts in try/ catch and at least that means the type won't fail to initialize, but surely if the initialization code is that critical, then this behavior is actually good - the type is not usable in this uninitialized state.

The other option is to do it as a singleton - each time you try and get the Instance you can create the type correctly, until you are successful, even if it fails the first time.

You would still need some error handling on the caller in case Instance returns you null the first (or second etc.) time.

Edit: And if you don't want a singleton, then just have your instance constructor initialize the static parts

e.g.

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

public T()
{
   lock(_lock)
   {
      if(!_initialized)
      {
         try
         {
           //Do static stuff here
         }
         catch(Exception ex_)
         {
           //Handle exception
         }
      } 
   }
}
樱花落人离去 2024-08-09 15:34:38

这里的教训非常简单:不要在静态构造函数中执行任何可能失败的操作。

The lesson here is pretty simple: don't do anything in a static constructor that could reasonably fail.

掀纱窥君容 2024-08-09 15:34:38

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

The workaround I used in the past is creating a Singleton. Make a static constructor fail if and only if the failure means the whole application can't run.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文