2016-12-28 47 views
1

我發現那個例子(Communicate between two windows forms in C#)工作正常,但不是當兩個窗體在不同的線程。c#飛濺屏幕和mainform之間的通信到不同的線程

我在MainForm中有一個「System.NullReferenceException」在第20行(this.splashy.LabelText = I)

這個腳本的一點是要修改在濺射屏幕時的進度的寬度MainForm正在完成他的工作。

在此先感謝!

這裏有兩個C#類和程序文件:

//Program.cs 
using System; 
using System.Threading; 
using System.Windows.Forms; 
namespace GIS 
{ 
    static class Program 
    { 
     public static SplashScreen splashy = null; 
     /// <summary> 
     /// Point d'entrée principal de l'application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Thread splashThread = new Thread(new ThreadStart(
      delegate 
      { 
       //SplashScreen splashy = new SplashScreen(); 
       splashy = new SplashScreen(); 
       Application.Run(splashy); 
      } 
      )); 
      splashThread.SetApartmentState(ApartmentState.STA); 
      splashThread.Start(); 
      //run form - time taking operation 
      MainForm mainForm = new MainForm(splashy); 
      mainForm.Load += new EventHandler(mainForm_Load); 
      Application.Run(mainForm); 
     } 
     static void mainForm_Load(object sender, EventArgs e) 
     { 
      //close splash 
      if (splashy == null) 
      { 
       return; 
      } 
      splashy.Invoke(new Action(splashy.Close)); 
      splashy.Dispose(); 
      splashy = null; 
     } 
    } 
} 

//SplashScreen.cs 
using System; 
using System.Windows.Forms; 
namespace GIS 
{ 
    public partial class SplashScreen : Form 
    { 
     public SplashScreen() 
     { 
      InitializeComponent(); 
     } 
     public int LabelText 
     { 
      get 
      { 
       return rectangleShape1.Width; 
      } 
      set 
      { 
       rectangleShape1.Width = value; 
      } 
     } 
    } 
} 

//MainForm.cs 
using System.Threading; 
using System.Windows.Forms; 
namespace GIS 
{ 
    public partial class MainForm : Form 
    { 
     private SplashScreen splashy = null; 
     public MainForm(Form callingForm) 
     { 
      splashy = callingForm as SplashScreen; 
      InitializeComponent(); 
      doWork(); 
     } 
     private void doWork() 
     { 
      for(int i = 0; i < 100; i++) 
      { 
      this.splashy.LabelText = i; 
      Thread.Sleep(10); 
      } 
     } 
    } 
} 

回答

0

您需要調用SplashScreen改變它從其他線程值一樣

this.splashy.Invoke((MethodInvoker) delegate { this.splashy.LabelText = "Requested" + repeats + "Times"; }); 

注意構造

splashy = callingForm as SplashScreen; 

允許splashy爲空 - 這會導致您的當前NullReferenceException

這個問題在此locaed剪斷:

 Thread splashThread = new Thread(new ThreadStart(
     delegate 
     { 
      splashy = new SplashScreen(); 
      Application.Run(splashy); 
     } 
     )); 
     splashThread.SetApartmentState(ApartmentState.STA); 
     splashThread.Start(); 
     //run form - time taking operation 
     MainForm mainForm = new MainForm(splashy); 

新的線程你開始時不是很快到足夠多的,你把它傳遞之前創建的SplashScreen實例。結果 - 你通過null

修復它通過你的線程開始之前創建聲勢浩大:

 splashy = new SplashScreen(); 
     Thread splashThread = new Thread(new ThreadStart(
     delegate 
     { 
      Application.Run(splashy); 
     } 
+0

嗨,THX您的回覆! –

+0

我仍然不清楚Invoke()如何工作,它說不可能將lambda表達式轉換爲委託類型... –

+0

對不起 - 我一個小錯誤 - 檢查編輯的答案! – Fruchtzwerg