-
Notifications
You must be signed in to change notification settings - Fork 0
ManagedTask Documentation (Russian)
ManagedTask - это класс, который предоставляет возможность выполнять и управлять асинхронными задачами в PHP. Он поддерживает продолжение задач, паузу, возобновление и отмену. Эта документация объясняет, как использовать ManagedTask в ваших PHP приложениях, с подробными объяснениями и примерами.
-
Id
: int - Получает уникальный идентификатор задачи. -
Status
: TaskStatus - Получает текущий статус задачи. -
IsCompleted
: bool - Указывает, завершена ли задача. -
IsCanceled
: bool - Указывает, была ли задача отменена. -
IsCompletedSuccessfully
: bool - Указывает, завершена ли задача успешно. -
IsFaulted
: bool - Указывает, произошла ли ошибка в задаче. -
IsPaused
: bool - Указывает, приостановлена ли задача. -
IsStarted
: bool - Указывает, запущена ли задача.
-
Completed
: event(EventHandler) - Возникает, когда задача завершена.
//Инициализирует новый экземпляр класса ManagedTask.
public function __construct(callable $callable)
- $callable: callable - PHP callable для выполнения в качестве задачи.
//Запускает задачу.
public function Start();
//Приостанавливает задачу.
public function Pause();
//Возобновляет задачу, если она была приостановлена.
public function Resume();
//Останавливает задачу.
public function Stop();
Ожидает завершения задачи.
public function Wait();
//Синхронно получает результат задачи.
public function GetResultSync();
//Создает задачу-продолжение, которая выполняется при завершении текущей задачи.
public function ContinueWith(callable $continuationAction): ManagedTask
- $continuationAction: callable - Действие, которое нужно выполнить при завершении задачи.
//Освобождает задачу и её ресурсы.
public function Dispose();
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Threading\Tasks\ManagedTaskEventArgs;
use Php\Output\Logger;
function simpleTask() {
// Симуляция работы
sleep(2);
return "Задача выполнена";
}
$managedTask = new ManagedTask('simpleTask');
$managedTask->Completed->add(function(ManagedTask $sender, ManagedTaskEventArgs $e) {
Logger::Info("Задача {$e->TaskId} завершена с результатом: {$e->Result}");
});
$managedTask->Start();
$managedTask->Wait();
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Threading\Tasks\ManagedTaskEventArgs;
use Php\Threading\Tasks\ManagedTaskException;
use Php\Output\Logger;
/**
* @throws Exception
*/
function taskWithError() {
throw new Exception("Что-то пошло не так!");
}
$managedTask = new ManagedTask('taskWithError');
$managedTask->Completed->add(function(ManagedTask $sender, ManagedTaskEventArgs $e) {
if ($e->Result instanceof ManagedTaskException) {
Logger::Error("Ошибка задачи: {$e->Result->getMessage()}");
} else {
Logger::Info("Задача {$e->TaskId} завершена с результатом: {$e->Result}");
}
});
try {
$managedTask->Start();
$managedTask->Wait();
} catch (ManagedTaskException $ex) {
Logger::Error("Пойманная ошибка задачи: {$ex->getMessage()}");
}
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Output\Logger;
use System\Threading\AutoResetEvent;
use System\Threading\CancellationToken;
function longRunningTask(CancellationToken $cancellationToken, AutoResetEvent $autoResetEvent): string
{
for ($i = 0; $i < 10; $i++) {
if ($cancellationToken->IsCancellationRequested) {
return "Задача отменена";
}
$autoResetEvent->WaitOne(); // Механизм паузы
Logger::Info("Этап задачи: $i");
$autoResetEvent->Set();
sleep(1); // Симуляция работы
}
return "Задача выполнена";
}
$managedTask = new ManagedTask('longRunningTask');
$managedTask->Start();
sleep(3); // Дать задаче немного поработать
$managedTask->Pause();
Logger::Info("Задача приостановлена");
sleep(3); // Пауза
$managedTask->Resume();
Logger::Info("Задача возобновлена");
$managedTask->Wait();
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Threading\Tasks\ManagedTaskEventArgs;
use Php\Output\Logger;
use System\Threading\AutoResetEvent;
use System\Threading\CancellationToken;
function initialTask(): string
{
return "Результат начальной задачи";
}
function continuationTask(CancellationToken $cancellationToken, AutoResetEvent $autoResetEvent, mixed $previousResult): string
{
return "Задача-продолжение с предыдущим результатом: $previousResult";
}
$managedTask = new ManagedTask('initialTask');
$continuedTask = $managedTask->ContinueWith('continuationTask');
$managedTask->Completed->add(function(ManagedTask $sender, ManagedTaskEventArgs $e) {
Logger::Info("Начальная задача завершена с результатом: {$e->Result}");
});
$continuedTask->Completed->add(function(ManagedTask $sender, ManagedTaskEventArgs $e) {
Logger::Info("Задача-продолжение завершена с результатом: {$e->Result}");
});
$managedTask->Start();
$managedTask->Wait();
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Threading\Tasks\ManagedTaskEventArgs;
use Php\Threading\Tasks\ManagedTaskException;
use Php\Output\Logger;
use System\Threading\AutoResetEvent;
use System\Threading\CancellationToken;
function taskWithCatch(CancellationToken $cancellationToken, AutoResetEvent $autoResetEvent)
{
try {
// Симуляция работы
$autoResetEvent->WaitOne();
// Здесь можно вызвать ошибку
throw new Exception("Ошибка внутри задачи");
$autoResetEvent->Set();
return "Задача выполнена";
} catch (Exception $ex) {
$autoResetEvent->Set();
return new ManagedTaskException($ex->getMessage());
}
}
$managedTask = new ManagedTask('taskWithCatch');
$managedTask->Completed->add(function(ManagedTask $sender, ManagedTaskEventArgs $e) {
if ($e->Result instanceof ManagedTaskException) {
Logger::Error("Ошибка задачи: {$e->Result->getMessage()}");
} else {
Logger::Info("Задача {$e->TaskId} завершена с результатом: {$e->Result}");
}
});
$managedTask->Start();
$managedTask->Wait();
<?php
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Output\Logger;
use System\Threading\Mutex;
use System\Threading\AutoResetEvent;
use System\Threading\CancellationToken;
class SyncTaskExample {
private Mutex $mutex;
public function __construct() {
$this->mutex = new Mutex();
}
public function taskWithSync(CancellationToken $cancellationToken, AutoResetEvent $autoResetEvent): string
{
for ($i = 0; $i <= 10; $i++) {
if ($cancellationToken->IsCancellationRequested) {
return "Задача отменена";
}
$autoResetEvent->WaitOne();
$this->mutex->WaitOne(); // Синхронизация задачи
try {
Logger::Info("Этап задачи: $i");
} finally {
$this->mutex->ReleaseMutex();
}
$autoResetEvent->Set();
sleep(1); // Симуляция работы
}
return "Задача выполнена";
}
}
$example = new SyncTaskExample();
$managedTask = new ManagedTask([$example, 'taskWithSync']);
$managedTask->Start();
$managedTask->Wait();
В этом примере мы используем Mutex для синхронизации доступа к критической секции кода. WaitOne на mutex блокирует текущий поток до тех пор, пока не будет получен доступ к критической секции, а ReleaseMutex освобождает этот доступ.
Пример 8: Скачивание изображения из интернета и сохранение рядом с программой с помощью HttpClient и ManagedTask
<?php
use Php\Threading\Tasks\ManagedTask;
use Php\Output\Logger;
use Php\Threading\Tasks\ManagedTaskEventArgs;
use Php\Threading\Tasks\ManagedTaskException;
use System\Net\Http\HttpClient;
use System\Net\Http\HttpRequestException;
use System\IO\FileStream;
use System\IO\FileMode;
use System\IO\FileAccess;
/**
* @throws ManagedTaskException
*/
function downloadImageTask($url): string
{
$httpClient = new HttpClient();
try {
$response = $httpClient->GetAsync($url)->Result;
$response->EnsureSuccessStatusCode();
$stream = $response->Content->ReadAsStreamAsync()->Result;
$filePath = __DIR__ . '/logo.png';
$fileStream = new FileStream($filePath, FileMode::Create, FileAccess::Write);
$stream->CopyTo($fileStream);
} catch (HttpRequestException $httpRequestException) {
return "Не удалось загрузить файл: " . $httpRequestException->Message;
} catch(Exception $exception) {
return "Ошибка в методе Load: " . $exception->getMessage();
} finally {
$httpClient->Dispose();
}
return "Изображение скачано и сохранено как logo.png";
}
$managedTask = new ManagedTask(function (){
return downloadImageTask("https://github.com/FibonacciFox/Peachpie.Avalonia/blob/master/Samples/Application/Assets/Logo.png?raw=true");
});
$managedTask->Completed->add(function(ManagedTask $sender, ManagedTaskEventArgs $e) {
Logger::Info($e->Result);
});
$managedTask->Start();
$managedTask->Wait();
$managedTask->Dispose();
В этом примере мы используем HttpClient для скачивания изображения из интернета и сохранения его на диск. GetAsync выполняет асинхронный запрос, а ReadAsStreamAsync считывает содержимое ответа как поток. Затем мы сохраняем этот поток в файл logo.png.
<?php
use Php\Threading\Tasks\ManagedTask;
use Avalonia\Threading\Dispatcher;
use System\Threading\AutoResetEvent;
use System\Threading\CancellationToken;
class AvaloniaUIExample {
private $textblock;
public function __construct($textblock) {
$this->textblock = $textblock;
}
public function updateUITask(CancellationToken $cancellationToken, AutoResetEvent $autoResetEvent): string
{
$counter = 0;
while (!$cancellationToken->IsCancellationRequested) {
$autoResetEvent->WaitOne();
Dispatcher::$UIThread->Post(function() use ($counter) {
$this->textblock->Text = "Счетчик: $counter";
});
$counter++;
sleep(1);
$autoResetEvent->Set();
}
return "Обновление UI завершено";
}
}
// Предположим, что $textblock это элемент Avalonia UI, который мы хотим обновлять
$textblock = ...;
$example = new AvaloniaUIExample($textblock);
$managedTask = new ManagedTask([$example, 'updateUITask']);
$managedTask->Start();
sleep(10); // Позволяем задаче обновлять UI в течение 10 секунд
$managedTask->Stop();
$managedTask->Wait();
В этом примере мы используем Dispatcher для обновления элемента UI из асинхронной задачи. Dispatcher::$UIThread->Post позволяет выполнить код в потоке UI, обеспечивая безопасное обновление элементов интерфейса.
- $autoResetEvent->WaitOne(): Ожидает сигнал, что позволяет приостановить выполнение задачи до тех пор, пока не будет получен сигнал для продолжения.
- $autoResetEvent->Set(): Устанавливает сигнал, разрешая продолжение выполнения задачи.
- $cancellationToken->IsCancellationRequested: Проверяет, была ли запрошена отмена задачи. Если да, выполнение задачи должно быть прервано.
- $this->mutex->WaitOne(): Блокирует текущий поток до тех пор, пока не будет получен доступ к критической секции.
- $this->mutex->ReleaseMutex(): Освобождает доступ к критической секции, позволяя другим потокам войти в неё.
Test