如何做一个静态构造函数工作? [英] How does a static constructor work?

查看:177
本文介绍了如何做一个静态构造函数工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 命名空间了myNameSpace
{
    静态MyClass类
    {
        静态MyClass的()
        {
            //验证过程..用户需要输入密码
        }        公共静态无效的MyMethod()
        {
            //取决于构造成功完成
        }
    }    类节目
    {
        静态无效的主要(字串[] args)
        {
            MyClass.MyMethod();
        }
    }
}

下面是我承担的序列


  1. 静态构造函数的开始

  2. 静态构造函数结束

  3. 开始
  4. 的MyMethod的开始

  5. 结束

现在在任何情况下,如果4将开始我拧2之前。这可能吗?


解决方案

您只能在这里问一个问题,但也有你的十几问题应的问,所以我会回答他们所有


  

下面是我承担的序列



  1. 类的构造函数开始(也称为 cctor

  2. cctor结束

  3. 主要的启动

  4. 的MyMethod启动


  

这是正确的?


没有。正确的顺序是:


  1. cctor为计划的开始,如果有一个。没有。

  2. cctor的程序结束,如果有一个。没有。

  3. 主要的开始

  4. cctor的入门MyClass的

  5. cctor结束了MyClass的

  6. MyClass.MyMethod的开始


  

如果有什么静态字段初始化?


的CLR允许改变在其中在某些情况下运行的静态字段初始顺序。查看详情主体乔恩的页面:

静态构造和类型初始化的区别

  

有没有可能像的MyMethod 的静态方法类的cctor完成之前被称为?


是的。的如果cctor本身调用的MyMethod那么很明显的MyMethod将在cctor完成之前调用。


  

该cctor不调用的MyMethod。有没有可能像的MyMethod 的静态方法的MyClass cctor完成之前被称为?


是的。的如果cctor使用其它类型的cctor调用的MyMethod随后的MyMethod将在MyClass的cctor完成之前调用。


  

没有cctors调用的MyMethod,直接或间接地!现在有没有可能像的MyMethod 的静态方法的MyClass cctor完成之前被称为?


没有。


  

是仍然如此,即使同时处理多个线程?


是的。该cctor将完成在一个线程之前静态方法可以在任何线程调用。


  

能否cctor被调用一次以上?假设两个线程都可以导致要运行的cctor。


该cctor是保证最多一次调用,无论多少线程是如何参与其中。如果两个线程调用的MyMethod在同一时间,那么他们的比赛。直到MyClass的cctor获胜线程完成一个人失去了种族和块。


  

败诉线程的的,直到cctor做?的真的的?


真的。


  

那么,如果在的获奖的线程调用code中的cctor上的锁$ P $块pviously采取的失去的线程?


然后你有一个经典的锁顺序反转的条件。您的程序死锁。永远的。


  

这似乎是危险的。如何避免死锁?


如果你那样做的话的停止这样做伤害了的。 永远不要做一些事情,可以在cctor阻塞。


  

这是个好主意,依靠cctor初始化语义来执行复杂的安全需求?而且它是一个好主意,有一个cctor,做用户交互?


也不是好主意。我的建议是,你应该找到一个不同的方法,以确保您的方法安全影响preconditions得到满足。

namespace MyNameSpace
{
    static class MyClass
    {
        static MyClass()
        {
            //Authentication process.. User needs to enter password
        }

        public static void MyMethod()
        {
            //Depends on successful completion of constructor
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass.MyMethod();
        }
    }
}

Here is the sequence which I assumed

  1. Start of static constructor
  2. End of static constructor
  3. Start of main
  4. Start of MyMethod
  5. End of main

Now in any scenario if 4 will start before 2 I am screwed. Is it possible?

解决方案

You only asked one question here but there are a dozen or so questions that you should have asked, so I'll answer them all.

Here is the sequence which I assumed

  1. Start of class constructor (also known as cctor)
  2. End of cctor
  3. start of Main
  4. start of MyMethod

Is this correct?

No. The correct sequence is:

  1. Start of cctor for Program, if there is one. There is not.
  2. End of cctor for Program, if there is one. There is not.
  3. Start of Main
  4. Start of cctor for MyClass
  5. End of cctor for MyClass
  6. Start of MyClass.MyMethod

What if there is a static field initializer?

The CLR is permitted to change the order in which static field initializers run in some cases. See Jon's page on the subject for details:

The differences between static constructors and type initializers

Is it ever possible for a static method like MyMethod to be called before the cctor of that class completes?

Yes. If the cctor itself calls MyMethod then obviously MyMethod will be called before the cctor completes.

The cctor does not call MyMethod. Is it ever possible for a static method like MyMethod to be called before the cctor of MyClass completes?

Yes. If the cctor uses another type whose cctor calls MyMethod then MyMethod will be called before the MyClass cctor completes.

No cctors call MyMethod, directly or indirectly! Now is it ever possible for a static method like MyMethod to be called before the cctor of MyClass completes?

No.

Is that still true even if there are multiple threads involved?

Yes. The cctor will finish on one thread before the static method can be called on any thread.

Can the cctor be called more than once? Suppose two threads both cause the cctor to be run.

The cctor is guaranteed to be called at most once, no matter how many threads are involved. If two threads call MyMethod "at the same time" then they race. One of them loses the race and blocks until the MyClass cctor completes on the winning thread.

The losing thread blocks until the cctor is done? Really?

Really.

So what if the cctor on the winning thread calls code that blocks on a lock previously taken by the losing thread?

Then you have a classic lock order inversion condition. Your program deadlocks. Forever.

That seems dangerous. How can I avoid the deadlock?

If it hurts when you do that then stop doing that. Never do something that can block in a cctor.

Is it a good idea to rely upon cctor initialization semantics to enforce complex security requirements? And is it a good idea to have a cctor that does user interactions?

Neither are good ideas. My advice is that you should find a different way to ensure that the security-impacting preconditions of your methods are met.

这篇关于如何做一个静态构造函数工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆