Reputation: 5226
I'm using Visual Studio 2012 RC with .Net 4.5 and ASP MVC 4 RC. It hangs whenever I use async at all. The controller action method uses async but is not itself an async controller method.
There are no errors logged or exceptions thrown, but the browser shows "Waiting for www.myweb.local" forever.
// Simplest possible async
public class Waiter
{
public async Task<int> GetValue()
{
await Task.Yield();
return await Task.Factory.StartNew(() => 42);
}
}
// simplest possible controller that uses the async
public class HomeController : Controller
public ActionResult Index()
{
var waiter = new Waiter();
var resultTask = waiter.GetValue();
int result = resultTask.Result;
// it never gets here
return View();
}
}
I have done the things that are noted in this answer, and it still does not work. ie. The web.config contains
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
And the magic words await Task.Yield();
are in the async method.
The .Net framework version is 4.5.50501. I have observed this behaviour on IIS Express and on IIS 6.0.
I tried applying the "July 2012 update" to VS2012, but that did not fix it.
This answer suggests that it may be because the task is already completed when I wait for it, however if that was the case, this should work and it does not:
public class Waiter
{
public async Task<int> GetValue()
{
await Task.Yield();
return await Task.Factory.StartNew(() =>
{
Thread.Sleep(1500);
return 42;
});
}
}
A couple of people have suggested that ConfigureAwait(false)
is needed, but this code does not work either:
public async Task<int> GetValue()
{
var task = new Task<int>(() => 42);
return await task.ConfigureAwait(false);
}
The following does work with the razor view engine, but not with spark. Surely there should be a way to get the other scenario working as well? Can one not use the async Tasks inside synchronous code?
public class Waiter
{
public async Task<int> GetValue()
{
return await Task.Factory.StartNew(() => 42);
}
}
public class HomeController : Controller
{
public async Task<ActionResult> IndexAsync()
{
await Task.Yield();
var waiter = new Waiter();
int result = await waiter.GetValue();
return View();
}
}
I know that is this isn't released software, but Microsoft's RCs are usually quite stable, so I'm surprised that it fails, and fails in an unhelpful way.
Upvotes: 9
Views: 9032
Reputation: 456457
You are causing a deadlock, just like this question.
James Manning's suggestion is correct, but you have to await
the result of ConfigureAwait
, like this:
public async Task<int> GetValue()
{
var task = new Task<int> (() => 42);
return await task.ConfigureAwait(false);
}
In general, mixing synchronous and asynchronous code is a Really Bad Idea unless you Really Know what you're doing. Making the controller action asynchronous would be much better.
Upvotes: 11
Reputation: 29776
I have had async working in the beta just fine. I've not tested it, but I'm guessing it's because your controller method is not async. Change it to this:
public async Task<ActionResult> IndexAsync()
{
var waiter = new Waiter();
int result = await waiter.GetValue();
// it never gets here
return View();
}
Upvotes: 1