I noticed another important point to keep in mind when writing async/await code in ASP.Net Web Forms code-behind, and that is to make sure Async="true" in the page declaration. This attribute is false by default.
If you do not do this then you could see your page in a forever-loading-state.
<%@ Page Language="C#" Async="true" %>
Also, in .Net 4.5, according to the answer by Stephen we need to have 'UseTaskFriendlySynchronizationContext' set to true in web config appsettings section. Another useful appsetting is AllowAsyncDuringSyncStages which needs to be false for async/await code in Webforms code-behind. These settings are both false by default.
<add key="aspnet:AllowAsyncDuringSyncStages" value="false" />
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
I had the following sample async/await code in an ASP.Net WebForm that ran very quickly using the above settings and using await all the way through as suggested by Stephen. If these recommendations are not followed then you could see the Webforms page loading forever in the browser.
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;
}
await
doesn't block as such... but yes: if there is some calling code that calls.Wait()
or.Result
, it will be a problem