2016-12-28 6 views
1

두 개의 양식이 다른 스레드에있을 때 작동하지만 잘 작동하지 않는 예제 (Communicate between two windows forms in C#)를 발견했습니다.스플래시 화면과 메인 폼 사이의 통신이 다른 스레드로

내가 MainForm에서 라인 (20)에서 "System.NullReferenceException"을 가지고

(this.splashy.LabelText = I)

이 스크립트의 포인트로 SplashScreen시에서 ProgressBar의 수정 폭이다 MainForm이 일을하고 있습니다.

미리 감사드립니다. 여기

는 두 개의 C# 클래스와 프로그램 파일입니다 : 당신은

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

주처럼이 다른 스레드에서 값의 변경합니다 SplashScreen를 호출 할 필요가

//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

그 생성자

splashy = callingForm as SplashScreen; 

splashy을 null로 설정할 수 있습니다. 현재 NullReferenceException. 이 문제는이에 locaed되어

을 냈다 : 당신이 시작 빨리 당신이 그것을 통과하기 전에 SplashScreen의 인스턴스를 생성 한 정도로되지

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

새로운 스레드입니다. 결과 - null을 전달합니다.

수정이에 의해 스레드가 시작되기 전에 화려한를 만듭니다

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

안녕, 들으 귀하의 회신! –

+0

나는 여전히 Invoke()가 작동하는 방식과 람다 식을 위임 된 형식으로 변환하는 것이 불가능하다고 말한 적이있다. –

+0

미안 - 나에 의한 실수 - 편집 된 대답을 확인하라! – Fruchtzwerg