2013-03-01 62 views
0

我仍然學習一些關於線程。我有一個經理類,它有一些基本的業務代碼,可以調用某些類的方法併爲視圖做好準備。這些方法轉到我在創建新線程時實例化的管理器類。當我嘗試調用類方法時,它會拋出一個空指針,即使我知道它是在其自己的線程中工作。線程類實例化,使用它時的空指針,C#

我假設正在發生的事情是當前嘗試調用方法的線程無法訪問新線程化的類方法。下面是一些代碼來解釋:

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

你得到一個空指針異常的原因是因爲當調用Manger.Test()時,你的工作線程構造了MyClass實例,還沒有執行。這種行爲不能保證,它只取決於你的線程是如何計劃的,哪些不在你的控制之下。

我認爲繼續學習線程是一個不錯的主意,並且包括一些關於如何同步不同線程上發生的操作的研究。

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(); 
    } 
}