2010-03-04 5 views
7

Ceci est ma première question sur StackOverflow (désolé pour mon anglais). Je vais essayer d'expliquer le problème aussi bien que je peux.Problème SWT avec syncExec()

J'ai une application swt avec une application jade de premier plan dans laquelle j'ai une barre de progression pour informer la durée de l'application. Pour actualiser cette barre de progression que j'utilise:

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

Progress est:

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); 
     }  
    } 
}; 

J'essaie d'analyser le temps que cette Runnable prend et il est constant, mais quand j'analyse cette ligne sSehll.getDisplay().syncExec(progress) prend différentes fois (entre 0 ms XXXXms)

J'ai lu ce

syncExec (Runnable runnable) caus es le thread actuel (s'il est différent du thread de l'interface utilisateur de l'affichage) pour attendre que le runnable se termine.

Mais le Runnable est constante de temps ...

Quelqu'un peut-il me guider? Je ne comprends pas pourquoi il faut parfois 3 minutes et une autre fois.

Merci

+1

+1, bienvenue dans StackOverflow! J'ai reformaté votre code pour vous, mais il n'y a pas besoin de s'excuser pour votre anglais :) –

+0

Merci à vous. Je sais que cela s'est passé il y a longtemps, mais j'ai été encouragé à participer aujourd'hui, enfin. – Michel

Répondre

1

Selon le Display class documentation, syncExec:

Causes la méthode run() du runnable à être invoqué par le fil de l'interface utilisateur à la prochaine occasion raisonnable . Le thread qui appelle cette méthode est suspendu jusqu'à ce que le runnable soit terminé. La spécification de null en tant que thread exécutable réveille simplement le thread d'interface utilisateur .

Par conséquent, votre méthode run est en cours d'exécution en temps constant, mais l'objet Display ne peut pas toujours appeler immédiatement.

+0

Je me souviens que quand j'ai lu la documentation, mais il n'y a aucun moyen de la forcer? – Michel

+1

Et si jamais syncExec prend trois minutes alors vous avez probablement du code exécuté dans le thread SWT, qui doit être placé dans un thread d'arrière-plan. Cela permettra à l'interface utilisateur de bien fonctionner à nouveau. –

3

Il existe deux méthodes dans la classe SWT Display, syncExec et aSyncExec. Ils sont tous deux utilisés lorsque vous avez un thread qui n'est pas le thread d'interface utilisateur qui souhaite mettre à jour l'interface utilisateur d'une manière ou d'une autre. Au fond, quand vous les appelez, vous dites essentiellement au thread de l'interface utilisateur que vous avez quelque chose que vous voulez qu'il fasse quand il a une chance. Ainsi, le thread d'interface continuera son travail actuel et à un moment donné, il fera ce que vous lui avez demandé de faire. Quand il le fait, il varie toujours en fonction de l'autre travail que le thread de l'interface utilisateur doit faire à ce moment-là.

La différence entre aSyncExec et syncExec est de savoir si le code qui l'appelle attend ou non que l'exécution se termine. Si vous appelez aSyncExec, l'exécution de l'instruction suivante dans votre thread appelant s'exécutera immédiatement. Si vous appelez syncExec, votre thread appelant reste assis et attend jusqu'à ce que le thread UI exécute le code et le renvoie. En chronométrant le temps nécessaire à l'exécution de syncExec, vous chronométrerz non seulement le temps d'exécution de la méthode d'exécution, mais également la durée avant que le thread d'interface ne commence à l'exécuter.

Ne soyez pas tenté d'échanger syncExec avec aSyncExec ici.Si vous chronométrez combien de temps il faut une exécution de SyncExec, vous trouverez que c'est encore plus rapide. Mais c'est parce que tout ce que vous chronométrez, c'est combien de temps il faut pour dire au thread de l'interface utilisateur que vous avez quelque chose à faire (et non pas combien de temps il faut pour le faire).

+0

Mais il n'y a aucun moyen de l'exécuter inmediatly? – Michel

+0

Non. Il devrait cependant s'exécuter assez rapidement, à moins que votre thread UI ne fasse beaucoup de travail (et si c'est le cas, vous pouvez regarder ce qu'il fait et essayer de faire fonctionner cela dans un thread différent). Si cela prend vraiment 3 minutes alors je suppose que votre thread UI fait quelque chose d'autre? Est-ce que c'est un travail lié à l'interface utilisateur? – DaveJohnston

+0

Oui, c'est lié ... – Michel