
TaskThreadPool - класс который управляет выполнением длительных задач
=========================================================================

.. currentmodule:: axioma.core

.. class:: TaskThreadPool

    Основная задача этого класса это запускать выполнение длительных 
    пользовательских задач. Это даёт возможность выполнять вычисления в фоне, оставляя 
    интерфейс отзывчивым. Результат выполнения задачи можно получить воспользовавшись методом 
    :meth:`~axioma.core.PythonProgressHandler.result` из интерфейса класса :class:`~axioma.core.PythonProgressHandler`

    .. method:: globalInstance()

        :return: Возвращает единственный объект класса
        :rtype: :class:`~TaskThreadPool`

    .. method:: start(task)

        :param task: Пользовательская задача
        :type task: :class:`~axioma.core.PythonTask`

        Запускает выполнение пользовательской задачи. Владение задачей переходит к :class:`~TaskThreadPool`
	
        .. warning:: 

            Не рекомендуется запускать несколько задач параллельно если они могут
            менять общие данные. В противном случае пользователь должен использовать
            различные механизмы синхронизации и блокировок

        .. warning::

            Запущенная задача будет выполняться не в основном потоке приложения. 
            Поэтому внутри задачи нельзя поднимать никакие диалоги или окна. Вероятнее 
            всего это приведёт к аварийному завершению приложения. Общаться с пользовательскими
            графическими элементами можно используя систему сигналов которую предоставляет Qt



Пример использования:

.. code-block:: python

    def user_heavy_function():
        # делаем необходимые вычисления
        return result

    task = PythonTask(user_heavy_function)
    progressHandler = task.progressHandler()
    TaskThreadPool.globalInstance().start(task)

    dialog = QProgressDialog()
    progressHandler.finished.connect(dialog.close)

    # проверяем не завершилась ли уже задача
    if not progressHandler.isFinished():
        dialog.exec_()

    print(progressHandler.result())

Полный пример лежит в директории ``<Axioma.X>/share/axioma/python_samples/concurrent/CustomProgressDialog``,
где ``<Axioma.X>`` - директория с установленным приложением Аксиома.

Т.к. функция :meth:`~axioma.core.TaskThreadPool.start` сразу 
возвращает поток управления, то чтобы дождаться результата 
нужно блокировать дальнейшее выполнение скрипта. Например вызвав 
:meth:`~PyQt5.QtWidgets.QDialog.exec_`. Если во фрагменте ниже заменить 
``exec_()`` на ``open()`` то вместо результата мы получим :class:`None`

.. code-block:: python

    TaskThreadPool.globalInstance().start(task)

    # проверяем не завершилась ли уже задача
    if not progressHandler.isFinished():
            dialog.exec_()
    print(progressHandler.result())

