C # Aprire un modulo, quindi chiuderlo da un altro metodo

Sono abbastanza nuovo in C # e ho un piccolo problema con qualcosa. Credo che il threading possa essere la risposta, ma questo è solo un Buzz-Word che ho raccolto quando cercavo soluzioni.

 namespace Test {public partial class Form1: Form {private Form2 form2;  public Form1 () {InitializeComponent ();  form2 = new Form2 ();  } private runCheck (origine object, System.Timers.ElapsedEventArgs e) {form2.ShowDialog ();  form2.TopMost = true;  } private void runCheckFalse () {form2.Hide ();  }} 

Questo è solo un rapido frammento di codice della mia applicazione spogliata, tuttavia quando provo questo viene visualizzato un errore: Operazione cross-thread non valida: controllo ‘Form2’ a cui si accede da un thread diverso dal thread su cui è stato creato.

Inoltre come nota a margine sto usando form2.TopMost = true; per tentare di aprire la finestra sopra tutto il resto , ma questo spesso finisce dietro Visual Studio ecc

È necessario utilizzare Invoke per lavorare con il modulo da un thread diverso.

Ecco un bell’articolo che spiega come utilizzare i controlli di Windows Form da più thread: Procedura: effettuare chiamate thread-safe ai controlli Windows Form

Prova questo:

 namespace Test { public partial class Form1 : Form { private Form2 form2; public Form1() { InitializeComponent(); form2 = new Form2(); } private void runCheck(object source, System.Timers.ElapsedEventArgs e) { if (form2.InvokeRequired) { form2.Invoke(new EventHandler(delegate { form2.ShowDialog(); form2.TopMost = true; })); } else { form2.ShowDialog(); form2.TopMost = true; } } private void runCheckFalse() { if(form2.InvokeRequired) { form2.Invoke(new EventHandler(delegate { form2.Hide(); })); } else { form2.Hide(); } } } } 

È ansible modificare il metodo runCheckFalse nel modo seguente: si tratta di uno schema abbastanza standard per Windows Form:

 private void runCheckFalse() { if(InvokeRequired) { BeginInvoke(new MethodInvoker(runCheckFalse)); return; } form2.Hide(); } 

In effetti, ciò che fa è controllare per vedere se stiamo correndo sul thread della GUI (“if InvokeRequired”). Se non lo siamo, ci chiamiamo sul thread della GUI e torniamo immediatamente. Se siamo in esecuzione sul thread della GUI, non è necessario fare nulla e continuare semplicemente con il metodo normalmente.

Se hai bisogno di usare i parametri:

 private void runCheckFalse(bool someParameter) { if(InvokeRequired) { BeginInvoke(new MethodInvoker(() => { runCheckFalse(someParameter);})); return; } form2.Hide(); } 

I controlli WinForm possono essere aggiornati solo dal thread dell’interfaccia utente. Date un’occhiata a questo post del blog , fornisce una serie di approcci per assicurarsi che l’aggiornamento si verifica sul thread dell’interfaccia utente. È un post lungo, ma vale la pena leggerlo. L’approccio rapido e sporco è il primo se non hai tempo di leggerlo.

Erick