0

私はまだスレッドについて少し学んでいます。特定のクラス メソッドを呼び出してビュー用に準備する基本的なビジネス コードを含むマネージャー クラスがあります。これらのメソッドは、新しいスレッドの作成中にインスタンス化するマネージャー クラスに送られます。クラス メソッドを呼び出そうとすると、独自のスレッド内で動作していることがわかっていても、null ポインターがスローされます。

私が想定しているのは、メソッドを呼び出そうとしている現在のスレッドが、新しくスレッド化されたクラス メソッドにアクセスできないということです。説明するコードを次に示します。

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

null ポインター例外が発生する理由は、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 に答える