Come rilevare se siamo su un thread dell’interfaccia utente?

Per ragioni, considera un thread dell’interfaccia utente come thread che ha avuto una chiamata a Application.Run() o uno dei suoi overload su di esso e ha un ciclo di messaggi attivo in esecuzione.

C’è un modo per scoprire se stiamo attualmente eseguendo su una tale discussione?

La ragione per cui voglio questo è perché ho una class con una funzione privata che è di lunga durata. La class stessa è già multithread e l’utilizzo di questa class è tale da poter essere utilizzato dall’interfaccia utente o dai thread in background che eseguono l’elaborazione. Questa funzione rientra anche in questa rete. Ma non voglio che blocchi il thread dell’interfaccia utente. Quindi voglio rilevare se sono in esecuzione su un thread dell’interfaccia utente e, in caso affermativo, forchetta la chiamata di funzione in un thread in background (probabilmente ThreadPool , ma non è un problema per questa discussione). Questo è del tutto ben fatto, ma i thread in background si basano probabilmente sull’output della funzione, quindi il blocco per essi è migliore, mentre il thread dell’interfaccia utente sta accedendo in un modo più “set-and-forget”.

Suggerirei che è il tipo di decisione che il chiamante dovrebbe prendere. Puoi sempre scrivere i metodi wrapper per renderlo più semplice, ma significa che non avrai problemi con il chiamante in una situazione “dispari” (ad es. Un framework UI di cui non sei a conoscenza, o qualcos’altro con un ciclo di eventi ) e stai prendendo la decisione sbagliata per loro.

Se il metodo ha sempre bisogno di fornire feedback nel thread corretto, passerei in un ISynchronizeInvoke (implementato da Control ) per farlo in modo agonistico.

Se si ha accesso a un Form o un Control , è ansible verificare la proprietà InvokeRequired ; questo restituirà false se si è sul thread dell’interfaccia utente e true se non lo si è .. Se si verifica in un contesto in cui non è ansible verificare un Control , è ansible impostare facilmente una proprietà statica nel programma a cui è ansible eseguire il controllo. Memorizza un riferimento a Thread.CurrentThread all’avvio e confronta Thread.CurrentThread con quel riferimento quando è necessario sapere:

 static class Program { private static Thread _startupThread = null; [STAThread] static void Main() { _startupThread = Thread.CurrentThread; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } public static bool IsRunningOnStartupThread() { return Thread.CurrentThread == _startupThread; } } 

Chiamando Program.IsRunningOnStartupThread otterrai un bool che ti dirà se lo sei o no.

bool isMessageLoopThread = System.Windows.Forms.Application.MessageLoop;

Si prega di vedere Rilevare in esecuzione nella discussione principale nella libreria C #