Настраиваемое действие Windows Workflow, которое выполняет асинхронную операцию - переделано с использованием универсального сервиса - PullRequest
2 голосов
/ 13 января 2009

Я пишу пользовательское действие Windows Workflow Foundation, которое запускает некоторый процесс асинхронно, а затем должно проснуться при наступлении асинхронного события.

Все примеры, которые я обнаружил (например, этот Кирк Эванс ), включают настраиваемую службу рабочего процесса, которая выполняет большую часть работы, а затем отправляет событие в очередь, созданную действием. Кажется, что основной причиной этого является то, что единственный метод для публикации события [который работает из потока, не относящегося к WF], это WorkflowInstance.EnqueueItem, и действия не имеют доступа к экземплярам рабочего процесса, поэтому они не могут публиковать события (из потока без WF, где я получаю результат асинхронной операции).

Мне не нравится этот дизайн, поскольку он разбивает функциональность на две части и требует добавления службы на хост при добавлении нового типа активности. Некрасиво.

Итак, я написал следующую общую службу, которую я вызываю из обработчика событий асинхронной операции, и которая может повторно использоваться различными асинхронными действиями (обработка ошибок опущена):

class WorkflowEnqueuerService : WorkflowRuntimeService
{
    public void EnqueueItem(Guid workflowInstanceId, IComparable queueId, object item)
    {
        this.Runtime.GetWorkflow(workflowInstanceId).EnqueueItem(queueId, item, null, null);
    }
}

Теперь в коде активности я могу получить и сохранить ссылку на эту службу, запустить мою асинхронную операцию, а когда она завершится, использовать эту службу, чтобы отправить событие в мою очередь. Преимущества этого - я храню весь код, относящийся к конкретной деятельности, внутри действия, и мне не нужно добавлять новые сервисы для каждого типа активности.

Но если посмотреть на официальные примеры и примеры из Интернета, это будут специализированные одноразовые сервисы, я хотел бы проверить, подходит ли этот подход, или я создаю здесь некоторые проблемы?

Ответы [ 2 ]

1 голос
/ 13 января 2009

Здесь есть потенциальная проблема с сохранением рабочего процесса.

Если вы создадите долго работающие рабочие потоки, которые сохраняются в базе данных, чтобы среда выполнения могла перезапустить эти рабочие процессы, не загруженные в память, пока не произойдет какое-либо внешнее событие, которое перезагрузит их. Поскольку там они ответственны за запуск события самостоятельно, но не могут, пока они не перезагружены. И у нас есть улов 22: - (

Правильный способ сделать это - использовать внешний сервис. И хотя это может показаться разделением кода на две части, на самом деле это не так. Причина в том, что рабочий процесс отвечает за общую картину, т.е. что нужно сделать. И служба времени выполнения отвечает за фактическую реализацию или как это должно быть сделано. Таким образом, вы можете изменить, как, не изменяя, почему и когда часть.

0 голосов
/ 22 июня 2009

Продолжение - независимо от всех причин, почему это «должно быть сделано» с помощью службы, это будет напрямую поддерживаться .NET 4.0, который обеспечивает чистый способ для активности начать асинхронную работу, одновременно приостанавливая постоянство активности.

См http://msdn.microsoft.com/en-us/library/system.activities.codeactivitycontext.setupasyncoperationblock(VS.100).aspx для деталей.

...