Async ctp MVC4 и рабочие процессы - PullRequest
0 голосов
/ 02 апреля 2012

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

public ActionResult Index()
    {
        var input = new Dictionary<string, object>();
        input["ViewData"] = this.ViewData;
        var userState = "BeginInvoke example";

        var invoker = new WorkflowInvoker(HelloMvcDefinition);

        Task workflowTask = Task.Factory.FromAsync<IDictionary<string, object>>(
            invoker.BeginInvoke(input, WorkflowCompletedCallback, userState),
            invoker.EndInvoke);

        workflowTask.Wait();

        return View();
    }

Я пробовал это, но я не могу заставить его работать:

public async Task<ActionResult> Index()
    {
        var input = new Dictionary<string, object>();
        input["ViewData"] = this.ViewData;
        var userState = "BeginInvoke example";

        var invoker = new WorkflowInvoker(HelloMvcDefinition);

        Task workflowTask = Task.Factory.FromAsync<IDictionary<string, object>>(
            invoker.BeginInvoke(input, WorkflowCompletedCallback, userState),
            invoker.EndInvoke);

        await workflowTask;

        return View();
    }

К сожалению, вид не работает. Есть идеи, что я делаю не так?

EDIT После получения совета я изменил метод на этот

public class HelloController : AsyncController
{
    private static readonly HelloWorkflow HelloMvcDefinition = new HelloWorkflow();

    public Task<ViewResult> Index()
    {
        var input = new Dictionary<string, object>();
        input["ViewData"] = ViewData;
        const string userState = "BeginInvoke example";

        var invoker = new WorkflowInvoker(HelloMvcDefinition);

        return Task.Factory.FromAsync<IDictionary<string, object>>(
            invoker.BeginInvoke(input, WorkflowCompletedCallback, userState),
            invoker.EndInvoke).ContinueWith(t => View());
    }       

    static void WorkflowCompletedCallback(IAsyncResult result)
    {

    }
}

Это прекрасно работает, поэтому проблема заключается в том, как я использую ключевое слово async.

Спасибо

Ответы [ 2 ]

1 голос
/ 14 июня 2013

Мы можем использовать шаблон TAP для запуска рабочего процесса Windows следующим образом: (Подробности указаны в моем блоге http://tweetycodingxp.blogspot.com/2013/06/invoke-workflow-wf-using-task-based.html)

public async Task<ActionResult> Index(string id)
{
    var wfInputArgs = new Dictionary<string, object>
    {
        ...
    };

    var wfOutputArgs = await Task<IDictionary<string, object>>.Factory.StartNew(
        () => WorkflowInvoker.Invoke(new MyWorkflow(), wfInputArgs));
    var result = wfOutputArgs["Output1"] as IEnumerable<Class1>;
    ...
    return View(model);
}
0 голосов
/ 03 апреля 2012

Производная от AsyncController вместо Controller.

РЕДАКТИРОВАТЬ: Вы также можете столкнуться с известной ошибкой , когда ASP.NET MVC4 будет зависать, если действие возвращает завершенное Task. Вы можете обойти эту ошибку, добавив await Task.Yield(); в начало метода action.

На несвязанной ноте этот код более эффективен (и тоже короче):

var workflowTask = Task.Factory.FromAsync(invoker.BeginInvoke, invoker.EndInvoke,
    input, userState);
...