Più thread UI – Winforms

Voglio creare più thread dell’interfaccia utente nella mia applicazione. Ho simulato lo scenario come di seguito. Sto creando una nuova finestra / modulo su un clic del pulsante in un thread in background

namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var thread = new Thread(() => { Form f = new Form(); Application.Run(f); }); // thread.IsBackground = true; -- Not required. See Solution below thread.SetApartmentState(ApartmentState.STA); thread.Start(); } } } 

Nota che – Sto facendo IsBackground = true bacause quando l’utente si chiude sul form principale, anche i form / windows secondari dovrebbero chiudersi. C’è un modo più pulito / aggraziato per raggiungere lo stesso?

EDIT – Voglio creare thread UI dedicati per ogni finestra. Avrò 10 windows di questo tipo che mostrano dati in tempo reale in parallelo.

Soluzione – Va bene? (come indicato dai commenti di msdn e Hans in basso) hanno impostato lo stato Apartment (vedi il codice sopra)

 protected override void OnClosed(EventArgs e) { Application.Exit(); } 

Pasticciare con i fili ti morderà solo prima o poi.

Da MSDN:

I controlli in Windows Form sono legati a un thread specifico e non sono thread-safe. Pertanto, se si chiama il metodo di un controllo da un thread diverso, è necessario utilizzare uno dei metodi di richiamo del controllo per eseguire il marshalling della chiamata al thread corretto

Ovviamente puoi usare tutti i thread che vuoi, ma non provare a creare una soluzione alternativa per poter utilizzare thread diversi per aggiornare l’interfaccia utente. Utilizzare Invoke / InvokeRequired dai thread worker / background.

L’utilizzo di un metodo di estensione lo rende più pulito: Automazione del pattern di codice InvokeRequired

Penso che dovrai impostare lo stato dell’appartamento della tua discussione su thread singolo come indicato qui ApartmentState for dummies e qui Form Thread-safe. Show : t.SetApartmentState(ApartmentState.STA) . Non so se è ansible su un thread in background.

Un’altra cosa che vorrei esortarvi a guardare è MDI (interfaccia per documenti multipli, ad es. Qui ). Hai davvero bisogno che forms diverse vengano visualizzate come una finestra o siano piuttosto documenti all’interno di un modulo comune? Ovviamente potresti avere un motivo per creare più thread dell’interfaccia utente.

È ansible gestire l’evento MainForm.Closing e chiamare subForm.Close (marshalling sul thread destro) per ogni sotto-modulo.

Non sono sicuro del motivo per cui vuoi i moduli su thread separati, però. Non puoi semplicemente visualizzare i moduli secondari non in modo modale sul thread principale?