PDA

View Full Version : [OPEN] [#946] DirectMethod with async await



baruch.gabo
Nov 06, 2013, 10:56 PM
I have a direct method that needs to retrieve information from several database tables before returning a result to the user. To improve performance we have implemented the data layer using the new async await functionality of .Net.
When using the data layer from within a DirectMethod we encountered one of two issues:

If we used the await by itself, the control returned to the DirectMethod invoke call and from there to the browser without the code getting a result. Which is expected since the DirectMethod Invoke code does not await a result from a task.
If we used the await with ConfigureAwait(false) option, the control waited until we got the result but HttpContext.Current becomes null, as well as Extnet.ResourceManager properties. Resulting in System.NullReferenceException

The following is a sample DirectMethod with a call to a delayed task to illustrate the first case:


[Ext.Net.DirectMethod]
public async Task<int> GetDmNumber(){
try{
var num = await GetNumberAsync();
num +=10;
return num;
}
catch(Excption ex){
Ext.Net.ResourceManager.AjaxSuccess = false;
Ext.Net.ResourceManager.AjaxErrorMessage = ex.Message;
}
}
private async Task<int> GetNumberAsync(){
await Task.Delay(1000);
return 5;
}
The following is the code that wait for the return value from the async function but fails to maintain the HttpContext resulting in a NullReferenceException for the AjaxSuccess


[Ext.Net.DirectMethod]
public async Task<int> GetDmNumber(){
try{
var num = await GetNumberAsync().ConfigureAwait(false);
num +=10;
throw Exception("test exception");
return num;
}
catch(Excption ex){
Ext.Net.ResourceManager.AjaxSuccess = false;
Ext.Net.ResourceManager.AjaxErrorMessage = ex.Message;
}
}
private async Task<int> GetNumberAsync(){
await Task.Delay(1000);
return 5;
}
Is there a way to use async await in a DirectMethod that will work?

Baidaly
Nov 07, 2013, 12:13 AM
Hello!

We'll investigate it.

Vladimir
Nov 07, 2013, 12:09 PM
Hi

Well, direct methods were not designed for server side async handlers (and we never tested such scenario)
I was able to make runable sample but I cannot guarantee that it will work in all cases


<%@ Page Language="C#" Async="true" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>


<!DOCTYPE html>


<html>
<head runat="server">
<title>Ext.NET v2 Example</title>


<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(GetDmNumber));
}

[Ext.Net.DirectMethod]
public async System.Threading.Tasks.Task<int> GetDmNumber(){
try{
var num = await GetNumberAsync();

int x = num + 10;
ResourceManager.DirectMethodResult = x;
return x;
}
catch(Exception ex){
Ext.Net.ResourceManager.AjaxSuccess = false;
Ext.Net.ResourceManager.AjaxErrorMessage = ex.Message;
}


return 0;
}

private async System.Threading.Tasks.Task<int> GetNumberAsync(){
await System.Threading.Tasks.Task.Delay(1000);
return 5;
}
</script>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:Button runat="server" Text="Get result" Handler="App.direct.GetDmNumber({success: function(result){alert(result);}})">
</ext:Button>
</form>
</body>
</html>


We will investigate possibility to add support of async direct methods in future releases

baruch.gabo
Nov 08, 2013, 3:57 PM
Thanks for the info, Vlad.
Registering the async DirectMethods in Page_Load worked in some of our cases but not all. Since DirectMethods don't officially support async, we'll go back to our old code.
For a future release, I think adding support for async DirectMethods would be great.

Vladimir
Nov 08, 2013, 5:07 PM
Can you post that invalid cases? It will be useful for us

baruch.gabo
Nov 08, 2013, 6:46 PM
The failed cases involve calling a combination of database/wcf async function before returning a result. Since these are proprietary, I can't share them. I'll see if I can translate the cases to a generic example.

Daniil
Feb 25, 2014, 12:20 PM
We are closing the thread for now. If you are able to create a sample(-s) ever, please feel free to post regardless the thread is closed.