当前位置: 动力学知识库 > 问答 > 编程问答 >

ASP.NET MVC 4 async child action

问题描述:

I have an ASP.NET MVC 4 application targeting .NET 4.5. One of our child actions makes a call out to a web service using HttpClient.

Since we're blocking on IO waiting for the HttpClient response, it makes a great deal of sense to convert the code to the async/await pattern. However, when MVC 4 attempts to execute the child action, we get the following error message:

HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete.

At first glance, it appears as though MVC 4 does not support async/await within a child action. The only remaining option is to run using synchronous code and force a "Wait" on the async task.

As we all know, touching .Result or .Wait() on an async task in an ASP.NET context will cause an immediate deadlock. My async logic is wrapped in a class library, so I can't use the "await blah.ConfigureAwait(false)" trick. Remember, tagging "async" on the child action and using await causes an error, and that prevents me from configuring the await.

I'm painted into a corner at this point. Is there any way to consume async methods in an MVC 4 child action? Seems like a flat out bug with no workarounds.

网友答案:

There are still parts of MVC that aren't async-friendly; I hope these will be addressed in the future. Please do create a Connect or UserVoice issue for this.

My async logic is wrapped in a class library, so I can't use the "await blah.ConfigureAwait(false)" trick.

You probably should add ConfigureAwait(false) to the calls in your class library (if you can).

You could also hack up an alternate solution. If your class library method doesn't need the ASP.NET context, then you could have a thread pool thread do the (a)waiting for you:

try
{
    var result = Task.Run(async () => { await MyHttpRequest(...); }).Result;
}
catch (AggregateException ex) { ... }

The effect is similar to ConfigureAwait(false): since MyHttpRequest runs in a thread pool context, it will not attempt to enter the ASP.NET context when it completes.

网友答案:

The format of Stephen's answer didn't quite work for me (maybe it's an async noob problem, but hey).

I had to do write the async expression in this format to get a strongly typed return value.

Person myPerson = Task.Run(() => asyncMethodWhichGetsPerson(id)).Result;
分享给朋友:
您可能感兴趣的文章:
随机阅读: