0

I have the below code which calls a workflow. I am wondering if I can changed the controller to be asynchronous using the 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();
    }

I have tried this but I cannot seem to get it to work:

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();
    }

Unfortunately the view does not seem to work. Any ideas on what I am doing wrong?

EDIT After taking advice I have changed the method to this

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)
    {

    }
}

Which works fine so the problem must be how I am using the async keyword.

Thanks

2
  • Can you explain the symptom more? Also, if you just change the await to .Wait() (leaving it marked async) does it start working again? Thanks Commented Apr 2, 2012 at 15:30
  • The problem seems to stem from the using async keyword. If I add the Wait() it still does not work. When I invoke this controller, the view should appear with the message being shown from the workflow but currently the browser just keeps spinning. Commented Apr 3, 2012 at 11:34

2 Answers 2

1

We can use the TAP pattern for invoking windows workflow as follows - (Details are mentioned in my blog post 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);
}
Sign up to request clarification or add additional context in comments.

Comments

0

Derive from AsyncController instead of Controller.

EDIT: You may also be experiencing a known bug where ASP.NET MVC4 will hang if the action returns a completed Task. You can work around this bug by adding await Task.Yield(); at the top of the action method.

On an unrelated note, this code is more efficient (and shorter, too):

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

6 Comments

Thanks for the response but unfortunately I see no change when this runs.
Thanks, but two things. 1, Has task.Yield() been changed to TaskEx.Yield(). 2, The shorter code does not even compile.
1. It's TaskEx.Yield in the CTP but it's Task.Yield in VS11. 2. Try specifying the generic arguments explicitly: Task.Factory.FromAsync<IDictionary<string, object>>(...)
Stephen - it still seems to be stuck even with TaskEx.Yield
What exactly do you mean when you say "stuck"? Does the workflow complete?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.