Как правильно используются методы publish() и process() в SwingWorker?

Эти два метода в SwingWorker сейчас меня смущают, и мне кажется, что их очень легко использовать неправильно.

Метод publish( ) описывает следующее:

Отправляет блоки данных в метод process(java.util.List). Этот метод должен использоваться внутри метода doInBackground для доставки промежуточных результатов для обработки в потоке отправки событий внутри метода процесса.

Для меня это означает, что пока мой рабочий поток выполняет свой doInBackground(), я могу создавать "фрагменты" (должны ли они быть чем-то конкретным или это просто способ сослаться на объекты сообщений?), а затем публиковать их для обработки на мой графический интерфейс Swing.

Это приводит меня к процесс(). В javadoc описано следующее:

Получает фрагменты данных от метода публикации асинхронно в потоке отправки событий.

Просмотрев документацию по обоим методам, может ли кто-нибудь прояснить, какой механизм стоит за тем, как это происходит? Я понимаю, что в соответствии с документацией это асинхронный процесс, но, поскольку он происходит в EDT, я полагаю, что в нем есть некоторая предсказуемость.

В документации publish() указано следующее:

Поскольку метод обработки вызывается асинхронно в потоке отправки событий, несколько вызовов метода публикации могут выполняться до выполнения метода обработки. В целях повышения производительности все эти вызовы объединяются в один вызов со связанными аргументами.

Подводя итог, мой вопрос состоит из двух частей:

  • Кто должен звонить process()?
  • Каков рабочий процесс для process() в контексте SwingWorker и EDT?

Пожалуйста, дайте мне знать, если необходимы какие-либо разъяснения.


person Surveon    schedule 30.08.2013    source источник
comment
process() — это обратный вызов. Вам не нужно звонить. process() вызывается библиотекой в ​​EDT.   -  person johnchen902    schedule 30.08.2013


Ответы (2)


Я написал программу, которая обрабатывает каталоги в поддереве. Обработка занимает достаточно много времени, поэтому пользователю нужна некоторая обратная связь о том, что что-то происходит. Я открываю диалоговое окно, содержащее метку с именем обрабатываемого в данный момент подкаталога; поток Swingworker, вызываемый publish() с именем каждого обрабатываемого каталога.

Нет никакой гарантии, что пользовательский интерфейс будет обновляться для каждого имени каталога — иногда обработка выполняется быстрее, чем повторное отображение, особенно если на компьютере происходит что-то еще, и в зависимости от компьютера, на котором работают вещи. Таким образом, publish() может вызываться и выполняться несколько раз без вызова process() средой выполнения Swing.

Как уже отмечалось, процесс не вызывается вашим кодом — он вызывается от вашего имени после вызова публикации и, возможно, не каждый раз, когда вы вызываете publish().

Это проясняет для вас ситуацию?

person arcy    schedule 30.08.2013
comment
Итак, что эффективно делает публикация, так это помещать свои фрагменты в какую-то очередь, которую процесс затем захватывает каждый раз, когда EDT вызывает ее.. это правильный способ взглянуть на это? - person Surveon; 30.08.2013
comment
да, и среда выполнения Swing (не совсем поток) что-то делает с любыми накопленными кусками сразу, если их больше одного. - person arcy; 30.08.2013

Вы должны вызвать publish(), чтобы добавить данные для обработки методом process().

Метод публикации можно вызывать из любого потока.

Метод процесса выполняется в потоке EDT, поэтому вам разрешено изменять элементы графического интерфейса только из потока EDT, поэтому вам не следует вызывать метод process() самостоятельно.

Вам решать, что должен делать ваш process(), но помните, что он выполняется в потоке EDT, поэтому он должен завершиться очень быстро.

person GerritCap    schedule 30.08.2013