这是一个困难的问题。使用完全相同的查询字符串,使用完全相同的以下代码:
using (var db = new SqlConnection(queryString))
{
await db.OpenAsync();
var results = await db.ExecuteSomethingAsync...;
db.Close();
{在windows应用程序中运行时将正常工作。然而,当从IIS Express或IIS7运行时,它将永远停留在await OpenAsync()中。如果我用db.Open()替换该行,它仍然可以工作。有什么建议吗?
发布于 2013-05-16 18:18:00
正如其他人所提到的,首先确保您的层次结构中没有Wait或Result调用。async方法链在依赖于框架的入口点结束。在UI/WebForms应用程序中,这通常是一个async void事件处理程序。在WebAPI/MVC应用程序中,这通常是一个async操作。
要检查ASP.NET的另外两件事是:
UseTaskFriendlySynchronizationContext设置为true.如果您需要在多个平台上的共享库中支持async,您可能会发现Microsoft.Bcl.Async NuGet库很有帮助。
发布于 2013-05-16 17:42:17
在ASP.NET中需要谨慎对待await,因为同步上下文希望序列化单个请求的工作。你发布的代码本身可能没问题-- await不会阻塞。但是,我预计在调用链中的某个位置,您将调用.Wait()或访问.Result,而不是await。
这里有几个选项:
.Wait()或.Result (或类似的)-相反,只使用await并使其成为正确的异步操作.ConfigureAwait(false)告诉它忽略同步上下文;不幸的是,这将需要添加到您await的所有位置,即await ().ConfigureAwait(False);var db.ExecuteSomethingAsync(...).ConfigureAwait(false);
中,并不是整个服务器都会停止运行
发布于 2015-04-03 22:40:44
我注意到在用ASP.Net Web Forms代码分离编写异步/等待代码时需要牢记的另一个要点,那就是确保页面声明中的Async=“为真”。默认情况下,此属性为false。
如果您不这样做,那么您可能会看到您的页面处于永久加载状态。
<%@ Page Language="C#" Async="true" %>此外,在.Net 4.5中,根据斯蒂芬的回答,我们需要在web配置应用程序设置部分将'UseTaskFriendlySynchronizationContext‘设置为true。另一个有用的应用程序设置是AllowAsyncDuringSyncStages,对于Webforms代码隐藏中的异步/等待代码,它需要为false。默认情况下,这两个设置都为false。
<add key="aspnet:AllowAsyncDuringSyncStages" value="false" />
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>我在一个ASP.Net WebForm中使用了下面的async/await示例代码,它使用上面的设置并按照斯蒂芬的建议一直使用await,运行速度非常快。如果不遵循这些建议,那么您可能会看到see表单页面在浏览器中永远加载。
protected async void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string sql = @"DELETE FROM dbo.Table1
WHERE Processed = 1";
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MainDB"].ConnectionString);
SqlCommand cmd = new SqlCommand(sql, conn);
int numberOfRecordsUpdated = await UpdateDatabaseAsync(conn, cmd);
}
}
public async Task<int> UpdateDatabaseAsync(SqlConnection conn, SqlCommand cmd)
{
int i = 0;
try
{
await conn.OpenAsync();
i = await cmd.ExecuteNonQueryAsync();
}
catch (Exception ex)
{
//log the error
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
finally
{
if (conn != null)
{
conn.Close();
conn.Dispose();
}
if (cmd != null)
{
cmd.Dispose();
}
}
return i;
}https://stackoverflow.com/questions/16583792
复制相似问题