简体   繁体   English

每当使用异步时,ASP.Net MVC 4控制器都会挂起

[英]ASP.Net MVC 4 controller hangs whenever async is used

I'm using Visual Studio 2012 RC with .Net 4.5 and ASP MVC 4 RC. 我正在使用带有.Net 4.5和ASP MVC 4 RC的Visual Studio 2012 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. 没有记录错误或抛出异常,但浏览器永远显示“正在等待www.myweb.local ”。

// 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 web.config包含

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>

And the magic words await Task.Yield(); 神奇的话语await Task.Yield(); are in the async method. 是在异步方法中。

The .Net framework version is 4.5.50501. .Net框架版本是4.5.50501。 I have observed this behaviour on IIS Express and on IIS 6.0. 我在IIS Express和IIS 6.0上观察到了这种行为。

I tried applying the "July 2012 update" to VS2012, but that did not fix it. 我尝试将“2012年7月更新”应用于VS2012,但这并没有解决它。

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: 有几个人建议需要ConfigureAwait(false) ,但是这段代码也不起作用:

    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. 以下适用于剃刀视图引擎,但不适用于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. 我知道这不是发布的软件,但是微软的RC通常都很稳定,所以我很惊讶它失败了,并且以无益的方式失败了。

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: James Manning的建议是正确的,但您必须await ConfigureAwait的结果,如下所示:

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. 使控制器操作异步会更好。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM