21 августа 2009 г.

Отображение прогрессбара и параллельное выполнение операции

В комментариях к прошлой статье мне подсказали, что для выполнения фоновых операций можно использовать класс ZendX_Console_Process_Unix из Zend Framework. Так как данный фреймворк распространяется на условиях лицензии BSD License, можно использовать его части, в частности, нас интересует только один класс, для своих проектов, дабы не таскать весь дистрибьютив размером под 90 МБ.

Данный метод не будет работать в Windows, потому что в классе ZendX_Console_Process_Unix используются функции pcntl_*, которые доступны только на Unix-платформах, например, Linux и Mac OSX.

Суть заключается в следующем: в "основной" ветке кода реализуем отображение окна с прогрессбаром, а в методе _run() класса MyProcess, который является наследником ZendX_Console_Process_Unix, выполняем операцию, которая может занять длительное время. В данном примере я имитировал операцию с помощью sleep().

Полный код программы:

<?php
 
// Файл с классом ZendX_Console_Process_Unix
include "Unix.php";
 
class MyProcess extends ZendX_Console_Process_Unix
{
/**
* Выполнение длительной операции в "фоне".
* В данном случае для имитации используется sleep().
*/

protected function _run()
{
echo "Запуск операции\n";
 
sleep(3);
 
echo "Операция завершена\n";
}
}
 
$thread = new MyProcess;
$thread->start();
 
$window = new GtkWindow();
$window->set_size_request(240, 90);
$window->set_position(Gtk::WIN_POS_CENTER);
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
 
$vbox = new GtkVBox();
 
$label = new GtkLabel("Идёт длительная операция.\nПожалуйста, подождите.");
$label->set_justify(Gtk::JUSTIFY_CENTER);
$vbox->pack_start($label, TRUE, TRUE);
 
$pulse = new GtkProgressBar();
$vbox->pack_start($pulse, FALSE, FALSE);
 
$timeout = Gtk::timeout_add(100, 'update_progressbar', $pulse);
 
$window->add($vbox);
$window->show_all();
Gtk::main();
 
/**
* Обновление прогрессбара.
* @param GtkProgressBar $pulse Полоса прогресса
* @return bool Для того, чтобы продолжить обновление прогрессбара необходимо вернуть TRUE
*/

function update_progressbar($pulse)
{
$pulse->pulse();
return TRUE;
}
 
?>

3 комментария:

zloiia комментирует...
Этот комментарий был удален автором.
Анонимный комментирует...

А как же быть с Windows системой? Там же это не будет работать...

Я уже все нервы потратил в поисках решения, ничего стоящего.

Shecspi комментирует...

К сожалению, на счет Windows я ничего не знаю, поэтому помочь ничем не смогу.