Проблема SWT с syncExec () - PullRequest
       12

Проблема SWT с syncExec ()

7 голосов
/ 04 марта 2010

Это мой первый вопрос по StackOverflow (извините за мой английский). Я постараюсь объяснить проблему так, как могу.

У меня есть приложение SWT с приложением Jade на переднем плане, в котором у меня есть индикатор выполнения для информирования о продолжительности приложения. Чтобы обновить этот индикатор, я использую:

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

Прогресс:

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

Я пытаюсь проанализировать время, которое занимает этот Runnable, и оно постоянно, но когда я анализирую эту строку, sSehll.getDisplay().syncExec(progress) занимает разное время (от 0 мс до XXXXms)

Я прочитал это

syncExec (Runnable runnable) заставляет текущий поток (если он отличается от потока пользовательского интерфейса дисплея) ждать завершения runnable.

Но Runnable - это постоянная времени ...

Может ли кто-нибудь направить меня? Я не понимаю, почему иногда это занимает 3 минуты, а иногда - другое.

Спасибо

Ответы [ 2 ]

3 голосов
/ 04 марта 2010

В классе отображения SWT есть два метода, syncExec и aSyncExec. Они оба используются, когда у вас есть поток, который не является потоком пользовательского интерфейса, который хочет каким-либо образом обновить пользовательский интерфейс. По сути, когда вы звоните им, вы в основном говорите потоку пользовательского интерфейса, что у вас есть то, что вы хотите, чтобы он делал, когда у него есть шанс. Таким образом, поток пользовательского интерфейса продолжит свою текущую работу и в какой-то момент выполнит то, что вы просили. Когда это происходит, оно всегда будет меняться в зависимости от того, какую работу должен выполнять поток пользовательского интерфейса в это время.

Разница между aSyncExec и syncExec заключается в том, ожидает ли код, который его вызывает, ожидание завершения выполнения. Если вы вызываете aSyncExec, то выполнение следующего оператора в вызывающем потоке будет выполнено немедленно. Если вы вызываете syncExec, то ваш вызывающий поток будет сидеть и ждать, пока поток пользовательского интерфейса фактически выполнит код и вернется. Посредством хронометража того, сколько времени требуется для выполнения syncExec, вы тем самым определяете время не только того, сколько времени потребуется для выполнения метода run, но также и того, сколько времени прежде чем поток пользовательского интерфейса фактически начнет его запускать.

Не пытайтесь поменять syncExec с aSyncExec здесь. Если вы определите время выполнения aSyncExec, вы обнаружите, что это еще быстрее. Но это потому, что все, что вы синхронизируете, - это сколько времени требуется, чтобы сообщить потоку пользовательского интерфейса, что у вас есть что-то для этого (а не сколько времени это займет).

1 голос
/ 04 марта 2010

Согласно документации класса Display , syncExec:

Вызывает метод run () может быть вызван Поток пользовательского интерфейса на следующем разумная возможность . Нить который вызывает этот метод приостановлен пока работоспособный не завершится. Указание null в качестве запускаемого просто будит пользовательский интерфейс нить.

Следовательно, ваш метод run выполняется в постоянное время, но объект Display не всегда может вызывать его немедленно.

...