Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 静态构造函数真的是线程安全的吗?_C#_.net - Fatal编程技术网

C# 静态构造函数真的是线程安全的吗?

C# 静态构造函数真的是线程安全的吗?,c#,.net,C#,.net,我的代码: using System; using System.Diagnostics; using System.Threading.Tasks; public class Program { private static void Main(string[] args) { var test = new Test(); // TypeInitializationException? var test2 = new Test

我的代码:

  using System;
  using System.Diagnostics;
  using System.Threading.Tasks;

  public class Program
  {
    private static void Main(string[] args)
    {
      var test = new Test();    // TypeInitializationException?
      var test2 = new Test();
    }

    public class Test
    {
      public Test()
      {
        Trace.WriteLine("Test Created");
      }

      static Test()
      {
        Task.Factory.StartNew(
                    () =>
                    {
                      throw new Exception();
                    });
      }
    }
  }
如果我将静态常量更改为:

  static Test()
          {
              throw new Exception();
          }
然后它抛出TypeInitializationException!我认为静态构造函数是线程安全的


在此上下文中,线程安全只意味着您不需要担心两个线程同时调用静态构造函数,或者一个线程启动静态构造函数,另一个线程认为它已经运行并跳过构造函数,即使它还没有完成对未初始化字段的访问


如果在构造函数中抛出异常,那只是一个错误。与线程安全无关。类型初始化错误非常严重,并且会一直发生,直到静态构造函数成功完成。

静态构造函数将所有抛出到TypeInitializationException中的异常包装到TypeInitializationException中,这些异常与线程安全无关

可以保证构造函数在第一次使用类型之前执行一次且仅执行一次,如果不使用类型,则不执行,这不取决于有多少线程访问该类型。这意味着它是线程安全的。

您通常应该避免使用它,因为它不会真正告诉您哪些操作是安全的,哪些操作是不安全的

相反,重要的是要明确说明在任何给定上下文中支持哪些与线程相关的操作和情况。这样,人们就可以客观、明确地说明是否违反了预期

C将确保静态构造函数在使用之前的某个时间点运行,无论有多少线程可能使用该类,或者当前是否有另一个线程正在运行静态构造函数

C将确保它不会多次运行静态构造函数,无论有多少个不同的线程可能同时使用同一个类,或者另一个线程是否在初始化该类时使用该类

规范特别指出,如果静态构造函数在运行时抛出异常,那么该类型的所有未来使用都将抛出TypeInitializationException,这就是您看到的


您看到的行为与规范中定义的行为完全一致。

线程安全性在代码中有什么作用?您是否想知道为什么第一个示例没有抛出TypeInitializationException?异常在其他线程中抛出,我的代码工作正常!如果我在任务中创建了测试类,并在任务中使用第二个常量抛出异常,那么所有线程都会出现异常TypeInitializationException可能重复的异常听起来你希望在线程之间可以观察到异常。事实并非如此。很抱歉使用了错误的术语,但对我来说似乎不一致。我已经更新了问题。好吧,这取决于你的观点。静态构造函数不是线程安全的。@oleksii根据我的回答,应该避免使用线程安全之类的术语。对于静态构造函数,C语言有一定的保证。他们相遇了。在这些限制条件下,有没有编写程序的方法来完成您可能不想做的事情。对任何可能的实现都是如此。不管您可能实现什么,总会有一些方法编写出一个不符合预期的程序,因为它不期望有任何保证。@Servy这听起来像是某种图灵定理风格的编程哲学=。但是听起来不错。谢谢你的链接。所有答案都是正确的,但是你的答案是第一个。
private static void Main(string[] args)
    {


      Task.Factory.StartNew(
                        () =>
                        {
                          var test = new Test();
                        });

      var test2 = new Test(); // HERE I GET THE EXCEPTION!!!!
    }

    public class Test
    {
      public Test()
      {
        Trace.WriteLine("Test Created");
      }

      static Test()
      {
        throw new Exception();
      }
    }
  }