Problem Summary:
I'm trying to use PageMethods to call a C# function from an HTML page. The problem is that the C# function I'm calling is marked as async and will await the completion of other functions. When the nested async C# functions are called by PageMethods, the C# code seems to deadlock.
I've given an example ASP.NET page with C# coded behind it to illustrate the idiom I'm trying to use.
Example WebForm1.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication3.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title></title></head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"/>
<div>
<input type="button" value="Show Function timing" onclick="GetTiming()"/>
</div>
</form>
</body>
<script type="text/javascript">
function GetTiming() {
console.log("GetTiming function started.");
PageMethods.GetFunctionTiming(
function (response, userContext, methodName) { window.alert(response.Result); }
);
console.log("GetTiming function ended."); // This line gets hit!
}
</script>
</html>
Example WebForm1.aspx.cs
using System;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Web.Services;
using System.Web.UI;
namespace WebApplication3
{
public partial class WebForm1 : Page
{
protected void Page_Load(object sender, EventArgs e) { }
[WebMethod]
public static async Task<string> GetFunctionTiming()
{
string returnString = "Start time: " + DateTime.Now.ToString();
Debug.WriteLine("Calling to business logic.");
await Task.Delay(1000); // This seems to deadlock
// Task.Delay(1000).Wait(); // This idiom would work if uncommented.
Debug.WriteLine("Business logic completed."); // This line doesn't get hit if we await the Task!
return returnString + "\nEnd time: "+ DateTime.Now.ToString();
}
}
}
Question:
I absolutely need to be able to call asynchronous code from my web page UI. I'd like to use async/await functionality to do this, but I haven't been able to figure out how to. I'm currently working around this deficit by using Task.Wait() and Task.Result instead of async/await, but that's apparently not the recommended long-term solution.
How can I await on server-side async functions in the context of a PageMethods call???
I really, really want to understand WHAT is happening under the covers here, and WHY it does NOT happen when the async method is called from a console app.
awaitdeadlocking and.Wait()not deadlocking doesn't make any sense. This is not really happening withTask.Delay. Is it? - Paulo Morgado