John,
Я согласен с тем, что ASP.NET не подходит для задач Async, как вы их описали, и не должно быть.
У нас были подобные ситуации в прошлом, и мы использовали решение, аналогичное тому, что вы описали. Таким образом, сохраните свою службу WCF под ASP.NET, используйте таблицу «Queue» с сервисом Windows как «QueueProcessor». Клиент должен опросить, чтобы убедиться, что работа выполнена (или использовать обмен сообщениями для уведомления клиента).
Мы использовали таблицу, содержащую процесс и его информацию (например, InvoicingRun). На этой таблице был статус (Pending, Running, Completed, Failed). Клиент представит новый InvoicingRun со статусом Pending. Служба Windows (процессор) проведет опрос базы данных, чтобы получить какие-либо прогоны, которые находятся на стадии ожидания (вы также можете использовать SQL-уведомление, поэтому вам не нужно опроса. Если ожидающий прогон был найден, он переместил бы его на работу, выполните обработку, а затем переместите ее в завершенную / неудачную.
В случае, когда процесс завершился неудачно (например, DB down, процесс был убит), запуск будет оставлен в рабочем состоянии, а вмешательство человека было Если процесс завершился неудачно в нефатальном состоянии (исключение, ошибка), процесс будет перенесен в сбой, и вы можете повторить попытку или иметь человеческий интервант.
Если было несколько процессоров, первый, чтобы переместить его в рабочее состояние, получил это задание. Вы можете использовать этот метод, чтобы предотвратить выполнение задания дважды. Альтернативный вариант - сделать выбор, а затем обновить до работы под транзакцией. Убедитесь, что любой из них за пределами транзакции больше транзакция. Пример (грубая) SQL:
UPDATE InvoicingRun
SET Status = 2 -- Running
WHERE ID = 1
AND Status = 1 -- Pending
IF @@RowCount = 0
SELECT Cast(0 as bit)
ELSE
SELECT Cast(1 as bit)
Rob