【问题标题】:Threading a class instantiation, null pointer when using it, C#线程化类实例化,使用时为空指针,C#
【发布时间】:2013-03-01 00:01:52
【问题描述】:

我还在学习一些关于线程的知识。我有一个经理类,它有一些基本的业务代码,可以调用某些类方法并为视图做准备。这些方法转到我在创建新线程时实例化的管理器类。当我尝试调用类方法时,它会抛出一个空指针,即使我知道它正在自己的线程中工作。

我假设正在发生的是试图调用该方法的当前线程无法访问新线程化的类方法。下面是一些代码来解释:

public class MyClass
{
    public void Test()
    {
        Console.WriteLine("Yay It is working");
    }
}

public class Manager
{
    public MyClass MyClass;
    private Thread myClassThread;

    public Manager()
    {
        myClassThread = new Thread(() => MyClass = new MyClass());
        myClassThread.Start();
    }

    public static void Main(string[] Args)
    {
        var manager = new Manager().MyClass;
        manager.Test();
    }

}

我还没有测试过这段代码是否可以编译,所以它背后的基本思想就是我想要表达的。我的假设是否正确,即我当前的线程无法访问新的 MyClass 测试方法,即使我可以访问在新线程中实例化的变量?我该如何解决这个问题?我应该在 Test 方法中而不是在管理器中放置一个新线程吗?多线程有标准吗?

【问题讨论】:

    标签: c# .net multithreading c#-4.0


    【解决方案1】:

    您收到空指针异常的原因是,当调用 Manger.Test() 时,构建 MyClass 实例的工作线程尚未执行。无法保证此行为,它仅取决于您的线程的调度方式,这不受您的控制。

    我认为继续学习线程是一个好主意,包括一些关于如何同步不同线程上发生的操作的研究。

    【讨论】:

      【解决方案2】:

      如果你的线程只创建了一个 MyClass 的实例然后离开,你可以在创建管理器后简单地加入线程:

      public static void Main(string[] Args)
      {
          Manager manager = new Manager();
          manager.myClassThread.Join();
          manager.MyClass.Test();
      }
      

      如果在您的实际代码中,您的线程创建了 MyClass 的实例,然后执行其他操作,那么您可以使用例如 AutoResetEvent 等到 MyClass 被实例化:

      public class Manager
      {
          public MyClass MyClass;
          public AutoResetEvent MyEvent;
          private Thread myClassThread;
      
          public Manager()
          {
              MyEvent = new AutoResetEvent(false);
              myClassThread = new Thread(() => {
                  MyClass = new MyClass();
                  MyEvent.Set();
                  Thread.Sleep(2000); // long running task
              });
              myClassThread.Start();
          }
      
          public static void Main(string[] Args)
          {
              Manager manager = new Manager();
              manager.MyEvent.WaitOne();
              manager.MyClass.Test();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 2012-03-06
        • 1970-01-01
        • 2022-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多