调用C#async方法不';Web应用程序中的t返回

调用C#async方法不';Web应用程序中的t返回,c#,async-await,C#,Async Await,我正在VS2013上的一个新的C#4.5 web应用程序中尝试异步/等待代码。它是一个web应用程序,运行在我的开发人员机器上,在IISExpress下。我正在异步方法中设置断点,可以看到该方法按预期完成。但是等待调用之后的下一行代码似乎没有被命中。我在那里有一个断点,它不会被击中,我已经尝试过单步遍历代码。它似乎被挂在那里无限地等待。我试着在一个控制台应用程序中运行相同的代码,这是可行的这让我想知道异步/等待调试是否在web应用程序中不起作用,或者它可能与IISExpress有关?还是我还遗漏

我正在VS2013上的一个新的C#4.5 web应用程序中尝试异步/等待代码。它是一个web应用程序,运行在我的开发人员机器上,在IISExpress下。我正在异步方法中设置断点,可以看到该方法按预期完成。但是等待调用之后的下一行代码似乎没有被命中。我在那里有一个断点,它不会被击中,我已经尝试过单步遍历代码。它似乎被挂在那里无限地等待。我试着在一个控制台应用程序中运行相同的代码,这是可行的这让我想知道异步/等待调试是否在web应用程序中不起作用,或者它可能与IISExpress有关?还是我还遗漏了什么?

代码非常基本,如下所示:

public async Task SomeMethodAsync(string parameter1)
{

}
protected void Button1_Click(object sender, EventArgs e)
{
    var task = RunSample();
    task.Wait();
}

private static async Task RunSample()
{
    await SomeMethodAsync("some value");
}
。。。调用上述异步方法的代码:

await SomeMethodAsync("some value");

我让它工作了。正是代码的结构(不包括在我的问题中)导致了这一点。事实上,它是一个Web表单应用程序,这似乎也是一个因素。原始代码如下所示:

public async Task SomeMethodAsync(string parameter1)
{

}
protected void Button1_Click(object sender, EventArgs e)
{
    var task = RunSample();
    task.Wait();
}

private static async Task RunSample()
{
    await SomeMethodAsync("some value");
}
结果表明,当异步方法运行时,代码的执行将进入按钮单击处理程序中的
task.Wait()
,并在那里等待。我没想到代码会出现在那里(这是我从控制台应用程序复制的代码…)

我决定将RunSample()代码移动到按钮单击处理程序中,就像这样,消除了RunSample():

这导致编译器最初出现错误,需要将Async=“true”添加到@Page指令中。完成后,它开始按预期工作。即使使用我的原始代码,以及那里的Async=“true”,这也不起作用。我认为关键是按钮点击处理程序要用
async
关键字标记


感谢@NielsFilter和@DaniCE的后续问题,让我进一步了解这一点。

您使用的是什么Web框架?如果您使用的是Asp.NETMVC,则必须在控制器中使用异步操作:代码是否运行过等待?将一些日志记录放在那里,看看这是否是一个“调试”问题,或者您的异步方法是否可能永远不会完成。@DaniCE,谢谢,这是一个经典的Web表单。@NielsFilter,我添加了3条debug.WriteLine语句。1在等待调用之前(“之前”),1在等待调用之后(“之后”),1在异步方法的最后(“完成”)。“before”和“completed”调试语句将出现,但“after”语句不会出现。这与我看到的断点一致。似乎异步方法完成了,然后等待语句后的下一行代码没有运行。@Ben,这是一种奇怪的行为,可以共享更多的代码吗?太好了。需要记住的一点是,尽量不要将.Wait和.Result等TPL方法与async和await混合使用。由于Wait实际上“捕获上下文”和.Wait和.Result都是阻塞的,等待Wait返回结果,因此可能会导致死锁。有关更多详细信息,请参见我博客中的异步陷阱第2条:我有一个详细描述这个问题的例子。你可能也会发现我的建议很有用。