0

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

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

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 方法中而不是在管理器中放置一个新线程吗?多线程有标准吗?

4

2 回答 2

4

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

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

于 2013-03-01T00:06:29.353 回答
0

如果你的线程只创建了一个 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();
    }
}
于 2013-03-01T14:11:32.030 回答