2010-03-04 10 views
7

Questa è la mia prima domanda su StackOverflow (mi dispiace per il mio inglese). Cercherò di spiegare il problema come posso.Problema SWT con syncExec()

Ho un'applicazione swt con un'applicazione in primo piano in cui ho una barra di avanzamento per informare la durata dell'applicazione. Per aggiornare questa barra di avanzamento che uso:

if(Display.getCurrent() != null) { 
    progress.run(); 
} 
else { 
    sShell.getDisplay().syncExec(progress); 
} 

Il progresso è:

Runnable progress = new Runnable() { 
    public void run() { 
     if (progressBar.isDisposed()) 
      return; 
     int percentage= (numStep*100)/maxSteps; 
     progressBar.setSelection(percentage); 
     if (numStep >= maxSteps){ 
      label1.setText("The simulation has been completed."); 
      button.setEnabled(true); 
     }  
    } 
}; 

cerco di analizzare il tempo che questo Runnable prende ed è costante, ma quando analizzo questa linea sSehll.getDisplay().syncExec(progress) prende tempi diversi (da 0 ms a XXXXms)

ho letto questo (eseguibile Runnable) caus

syncExec es il thread corrente (se è diverso dal thread dell'interfaccia utente del display) per attendere che il runnable termini.

Ma la Runnable è costante di tempo ...

Può qualcuno mi guida? Non capisco perché a volte occorrono 3 minuti e qualche altra volta.

Grazie

+1

+1, benvenuto su StackOverflow! Ho riformattato il codice per te, ma non è necessario scusarsi per il tuo inglese :) –

+0

Grazie a te. So che questo si è seduto molto tempo fa, ma alla fine sono stato incoraggiato a partecipare, finalmente. – Michel

risposta

1

Secondo la Display class documentation, syncExec:

causa il metodo run() della eseguibile per opporre il filo dell'interfaccia utente alla prossima ragionevole possibilità . Il thread che chiama questo metodo è sospeso fino al completamento del runnable. Specificare null come eseguibile semplicemente riattiva il thread dell'interfaccia utente .

Pertanto, il metodo run è in esecuzione in tempo costante, ma l'oggetto Display non può sempre chiamare immediatamente.

+0

Lo ricordo quando leggo la documentazione, ma non c'è modo di forzarla? – Michel

+1

E se mai si impiega syncExec per tre minuti, probabilmente il codice verrà eseguito nel thread SWT, che dovrebbe essere inserito in un thread in background. In questo modo l'interfaccia utente tornerà a funzionare senza problemi. –

3

Esistono due metodi nella classe Visualizzazione SWT, syncExec e aSyncExec. Vengono entrambi utilizzati quando si dispone di un thread che non è il thread dell'interfaccia utente che desidera aggiornare l'interfaccia utente in qualche modo. Fondamentalmente quando li chiami stai praticamente dicendo al thread dell'interfaccia utente che hai qualcosa che vuoi che faccia quando ne ha la possibilità. Quindi il thread dell'interfaccia utente continuerà il suo lavoro corrente e ad un certo punto farà ciò che gli hai chiesto di fare. Quando lo fa, varierà sempre in base agli altri lavori che il thread dell'interfaccia utente deve fare in quel momento.

La differenza tra aSyncExec e syncExec è se il codice che lo chiama attende che l'esecuzione termini. Se si chiama aSyncExec, l'esecuzione della successiva istruzione nel thread chiamante verrà eseguita immediatamente. Se chiami syncExec, il thread chiamante si posizionerà e attenderà fino a quando il thread UI esegue effettivamente il codice e restituisce. Calcolando quanto tempo ci vuole per eseguire syncExec, non si ha quindi la tempistica non solo per quanto tempo impiega il metodo di esecuzione, ma anche per quanto tempo prima che il thread dell'interfaccia utente inizi ad eseguirlo.

Non tentare di scambiare syncExec con aSyncExec qui.Se si impiega quanto tempo ci vuole aSyncExec per l'esecuzione, si scoprirà che è ancora più veloce. Ma questo perché tutto quello che hai tempo è quanto tempo ci vuole per dire al thread dell'interfaccia utente che hai qualcosa da fare (non quanto tempo ci vuole per farlo).

+0

Ma non c'è modo di eseguirlo inmediatamente? – Michel

+0

No. Dovrebbe essere eseguito piuttosto rapidamente, a meno che il thread dell'interfaccia utente non stia facendo molto lavoro (e se questo è il caso, potresti voler vedere cosa sta facendo e provare a farlo funzionare in un thread diverso). Se ci vogliono veramente 3 minuti, suppongo che il thread dell'interfaccia utente stia facendo qualcos'altro? E 'lavoro di UI che sta facendo? – DaveJohnston

+0

Sì, è correlato ... – Michel