Palych wrote:Нарисовать очереди можно, но хотелось бы иметь абстракцию для асинхронных вычислений приближенную к традиционным вычислениям:
Code: Select all
try {
doThis();
if (itIs()) {
doThat();
} else {
doSomethingElse();
}
} catch(error) {
handleError(error);
} finally {
finishThat();
}
Чтобы не пришлось рисовать кучу переменных и хитрым образом изменять их значение только для того чтобы обеспечить выполнение алгоритма...
Палыч, я подобное нарисовал на коленке для Qt-шного C++ проекта. Довольно просто, а адаптировать на разные платформы штуки вроде MS Parallel Patterns Library желания не было.
В вашем фрейморвке есть система обмена async-сообщениями? Если есть, половина дела сделана. Если нет, то очередь, блокировки, распознование, какому объекту предназначено сообщение, как подписчику, довольно банально. Паттерн (слово матершинное) publisher-subscriber, можно хоть центральный объект-диспатчер прикрутить.
doThat, doSomethingElse. No... make it AsyncDoThatTask->Perform() и AsyncDoSomethingElse->Perform(). You need to encapsulate the task and its continuation. Для прикладных целей вполне подойдёт завести некоторый класс AsyncTask, а в нём
static Map<Signal, AsyncTask>. Ессно, в программе есть получатель async сообщений о завершении предыдущих действий, хоть один поток занят ловлей сообщений, или ещё как. Signal направляет на следующее действие. Абстрактный метод AsyncTask->Perform(p) может иметь параметр data нравящегося вам типа.
Finally() может быть абстрактным методом AsyncTask, обязательным для имплементации у каждого потомка класса?
HandleError() может быть абстрактным методом AsyncTask, с дефолтной имплементацией/обязательным для имплементации у каждого потомка класса?
Ну, и деталь имплементации, явно даём поток для AsyncTask или у нас есть в фреймворке поддержка task-based concurrency?
... and even then it's rare that you'll be going there...