2009-04-28 9 views
6

Abbiamo un'applicazione desktop che esegue un insieme di calcoli piuttosto rigoroso in un thread in background. Parti di questo calcolo vengono eseguite in una libreria non gestita a cui accediamo tramite l'interoperabilità. Quello che stiamo scoprendo è che, quando iniziamo il calcolo, il thread dell'interfaccia utente non risponde per la durata del calcolo. Avevamo l'impressione che il framework gestisse il cambio di thread per consentire all'interfaccia utente di continuare a rispondere, ma non è così. Abbiamo scoperto che possiamo inserire Thread.Sleep (0) o Application.DoEvents() per consentire all'interfaccia utente di rispondere. Questo ha l'effetto collaterale di rallentare il calcolo. Inoltre, porzioni del calcolo eseguite dal codice non gestito possono richiedere fino a 30 secondi per essere completate e durante questo periodo l'applicazione non risponde mai. L'intero calcolo può richiedere da due a cinque minuti per essere completato.Modello di threading .NET e Application.DoEvents vs. Thread.Sleep

Questo porta alle seguenti domande:

  • Qual è il modello di threading .NET framework per quanto riguarda l'interfaccia utente e di interoperabilità?
  • Siamo errati nell'assumere che il framework debba gestire il cambio di thread tra lo sfondo e i thread dell'interfaccia utente?
  • Qual è la differenza tra l'uso di Thread.Sleep e Application.DoEvents in questa situazione, ed è uno preferito rispetto all'altro?
+0

NOTA: molto vecchio Q & A; cerca nuove discussioni per ottenere buone risposte sulle soluzioni disponibili oggi. – ToolmakerSteve

risposta

2

È possibile abbassare la priorità del thread in background, quindi verrà preimpostato dal sistema operativo. Se hai una conoscenza del dominio che ti porta a voler controllare quando è stata prorogata, potresti andare con Thread.Sleep (0) che arrende il tuo timeslice se c'è un altro thread in attesa.

Application.DoEvents pompa la coda dei messaggi di Windows. Ciò farà sì che la tua app risponda ad eventi come battiture di tasti o ridimensionamenti delle finestre. Thread.Sleep causerà il preempimento del thread (o forse no, nel caso di Thread.Sleep (0)).

visualizzato anche Threading in C#

0

Il modo corretto per farlo è quello di utilizzare le richiamate, però. Consultare il modello Silverlight di utilizzo dei metodi asincroni (per il recupero dei dati del servizio Web, ad esempio). So che questa domanda è "risposta" ma la risposta non è ideale IMHO.

2

La soluzione migliore è creare il proprio Thread. DoEvents e Thread.Sleep(0) blocca il calcolo, rallentandolo. È possibile includere le chiamate DLL in un delegato ThreadStart o un delegato ParameterizedThreadStart e utilizzare il nome del delegato come parametro quando si crea un'istanza di Thread. Da lì, tutto ciò che devi fare è chiamare il metodo di avvio di Thread.