Tasker: Керування фоновими завданнями
tasker - це модуль для запуску довготривалих завдань у фоні GTK-додатку без заморожування UI. Він надає простий, уніфікований API як для I/O-зв'язаних (asyncio), так і для CPU-зв'язаних (multiprocessing) завдань.
Основні концепції
task_mgr: Глобальний синглтон-проксі, який ви використовуєте для запуску та скасування всіх завданьTask: Об'єкт, що представляє одне фонове завдання. Ви використовуєте його для відстеження статусуExecutionContext(context): Об'єкт, що передається як перший аргумент у вашу фонову функцію. Ваш код використовує його для звітування прогресу, надсилання повідомлень та перевірки скасуванняTaskManagerProxy: Потокобезпечний проксі, що пересилає виклики до фактичного TaskManager, що працює в головному потоці
Швидкий старт
Всі фонові завдання керуються глобальним task_mgr.
Запуск I/O-зв'язаного завдання (наприклад, мережа, доступ до файлів)
Використовуйте add_coroutine для async функцій. Вони легковагі та ідеальні для завдань, що очікують на I/O.
import asyncio
from rayforge.shared.tasker import task_mgr
# Ваша фоновая функція ПОВИННА приймати `context` як перший аргумент.
async def my_io_task(context, url):
context.set_message("Завантаження...")
# ... виконати асинхронне завантаження ...
await asyncio.sleep(2) # Симуляція роботи
context.set_progress(1.0)
context.set_message("Завантаження завершено!")
# Запустіть завдання з вашого UI коду (наприклад, клік кнопки)
task_mgr.add_coroutine(my_io_task, "http://example.com", key="downloader")
Запуск CPU-зв'язаного завдання (наприклад, важкі обчислення)
Використовуйте run_process для звичайних функцій. Вони виконуються в окремому процесі щоб уникнути GIL та зберегти UI відгуковим.
import time
from rayforge.shared.tasker import task_mgr
# Звичайна функція, не async.
def my_cpu_task(context, iterations):
context.set_total(iterations)
context.set_message("Обчислення...")
for i in range(iterations):
# ... виконати важкі обчислення ...
time.sleep(0.1) # Симуляція роботи
context.set_progress(i + 1)
return "Фінальний результат"
# Запустіть завдання
task_mgr.run_process(my_cpu_task, 50, key="calculator")