MVC - Asynchronous method acts different from synchronous method
MVC - Asynchronous method acts different from synchronous method
I had this method:
public ActionResult AjaxHourLinesDataGridHandler(DataTablesParam param, DateTime? dateParam, int client)
{
if (client == 0) return null;
var clientObject = db.GetCurrentClients(User).FirstOrDefault(c => c.ClientId.Equals(client));
if (clientObject == null) return null;
var hourlines = db.GetHourLinesUpTillDateByClient(clientObject, dateParam.Value).OrderBy(h => h.Project.Description).ThenBy(h => h.From);
var count = hourlines.Count();
var result = hourlines.ToList()
.Select(hourline => new[] {
hourline.Code
hourline.From.ToString("dd-MM-yyyy"),
hourline.User.FirstName + " " + hourline.User.LastName,
string.Format(CultureInfo.InvariantCulture, "{0:N2}", hourline.Hours),
hourline.ProjectCode,
hourline.Description
}).ToList();
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = count,
iTotalDisplayRecords = param.iDisplayLength,
aaData = result
},
JsonRequestBehavior.AllowGet);
}
It worked just fine.
I changed it to something asynchronous:
public async Task<ActionResult> AjaxHourLinesDataGridHandler(DataTablesParam param, DateTime? dateParam, int client)
{
if (client == 0) return null;
var clientObject = await db.GetCurrentClients(User).FirstOrDefaultAsync(c => c.ClientId.Equals(client));
if (clientObject == null) return null;
var hourlines = db.GetHourLinesUpTillDateByClient(clientObject, dateParam.Value).OrderBy(h => h.Project.Description).ThenBy(h => h.From);
var count = hourlines.Count();
var listResult = await hourlines.ToListAsync();
var result = listResult
.Select(hourline => new[] {
"<input type=\"button\" id=\"devaluate"+hourline.HourLineId+"\" name=\"devaluate"+hourline.HourLineId+"\" value=\"afw\" class=\"btn-xs " + (hourline.HourlineStatus != null && !hourline.HourlineStatus.Description.Equals("Open") ? "btn-danger" : "btn-info") + "\" /><input type=\"checkbox\" name=\"charge\" id=\"charge"+hourline.HourLineId+"\" " + (hourline.HourlineStatus != null && hourline.HourlineStatus.Description.Equals("Open") ? "checked=\"checked\"" : string.Empty) + " style=\"margin-left: 5px;\" " + (hourline.HourlineStatus != null && !hourline.HourlineStatus.Description.Equals("Open") ? "disabled=\"disabled\"" : string.Empty) + " />",
hourline.From.ToString("dd-MM-yyyy"),
hourline.User.FirstName + " " + hourline.User.LastName,
string.Format(CultureInfo.InvariantCulture, "{0:N2}", hourline.Hours),
hourline.ProjectCode,
hourline.Description
}).ToList();
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = count,
iTotalDisplayRecords = param.iDisplayLength,
aaData = result
},
JsonRequestBehavior.AllowGet);
}
And as soon as I step over the third line of code (the first await), it jumps back to Internet Explorer (or Firefox) and shows me an Ajax error (which ends with /tn/7). I've debugged it as far as seeing the GetCurrentClients() method return what I need, so the problem is when Its running the FirstOrDefaultAsync. I've seen other async methods work fine. For example:
public async Task<ActionResult> AjaxProjectDataGridHandler(DataTablesParam param, int client, DateTime dateParam)
{
var clientObject = db.GetCurrentClients(User).Single(c => c.ClientId.Equals(client));
var yearAndProjects = db.GetHourLinesUpTillDateByClient(clientObject, dateParam).OrderBy(h => h.Project.Code).ThenBy(h => h.ProjectYear.HasValue ? h.ProjectYear : 0).GroupBy(h => new { h.ProjectYear, h.Project.Code, h.Project.Description, h.Project.ProjectId });
var count = yearAndProjects.Count();
var listResult = await yearAndProjects.ToListAsync();
var result = listResult.Select(
item => new[] {
"test"
});
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = count,
iTotalDisplayRecords = param.iDisplayLength,
aaData = result
},
JsonRequestBehavior.AllowGet);
}
As I looked at the difference, I noticed this is only using ToListAsync, which is also in the other method. I tried removing the asynchronous part from the FirstOrDefault (3rd line in the erroring method) and the code works. Do you know why? I know it's only a minor performance thing and won't be noticeable, but I'm trying to be consistent. Other than that, I want to know why one works and the other doesn't and whether it's something in .Net, Ajax, the browser or Datatables.
Answers
Can I bump this?
Does anyone have any idea?