0
   public async Task<Utils.TReportReturn> GetReportDataColumnSettings(AdminTechnicianReportInput input)
    {
        input.CustomerId = m_customerId;
        input.UserId = m_userId;
        input.TimeOffset = m_timeOffset;
        TReportReturn objTReportReturn = new TReportReturn();
        objTReportReturn.ReportColumns = await new ReportsEntityContext().GetTechniciansReportColumns<AdminTechnicianReportInput>(input);
        objTReportReturn.ReportSettings = await new ReportsEntityContext().GetGeneralSettingsData<AdminTechnicianReportInput>(input);
        objTReportReturn.ReportData = await new ReportsDbContext().GetUserListDynamic<AdminTechnicianReportInput>(input);
        return objTReportReturn;
    }

public class HomeController : Controller
{
    public ActionResult Index()
    {
        AdminTechnicianReportInput objInput = new AdminTechnicianReportInput();
        objInput.CustomerId = 1;
        objInput.UserId = 5477;
        objInput.AddUpdateUserid = 0;
        objInput.intRowsPerPage = 200;
        objInput.intPageIndex = 0;
        objInput.intTarget = 0;
        objInput.intStatusId = 0;
        objInput.strSearchQuery = "";
        objInput.strSortColumn = "Id";
        objInput.strSortDirection = "ASC";


        var result = new ReportsModel(1, 5477, 0).Administration.AdminTechnicianReport.GetReportDataColumnSettings(objInput).Result;

        ViewBag.Title = result.ReportSettings.CustomerName + "__" + result.ReportSettings.PrintedOn;           

        return View();
    }

}

The GetReportDataColumnSettings function calls many async methods which is the the model library dll.

Index() method in HomeController is an mvc method and I want to get the return in the result variable. Itried getawaiter().getmethod(), but it didn't worked.

I do not prefer to change the Index() method as asynk Task. Please suggest another way to get the result

1 Answer 1

2

I do not prefer to change the Index() method as asynk Task.

Why not? That is by far the easiest and most correct solution.

The second easiest is to just make everything synchronous. That is, if you won't go async all the way, then go sync all the way.

There are a variety of hacks for calling async from sync code that may or may not work in your situation; none of these hacks work everywhere. For more details, see my async brownfield article.

In your case, your initial attempt was to use the Blocking Hack. For this to work appropriately on the pre-Core ASP.NET, you'd have to use ConfigureAwait(false) for every await in that entire method call tree. This is usually possible (not always possible, of course, because library code may or may not use it), but it causes maintenance problems (forget just one, and you've got a race condition that may end in deadlock). I explain why the deadlock happens in detail on my blog.

If you won't go async all the way, and if you can't go sync all the way, then I'd recommend the Boolean Sync Argument Hack, which requires the entire call stack to support both synchronous and asynchronous callers. It would look something like this for the code you posted:

private async Task<Utils.TReportReturn> DoGetReportDataColumnSettingsAsync(AdminTechnicianReportInput input, bool sync)
{
  input.CustomerId = m_customerId;
  input.UserId = m_userId;
  input.TimeOffset = m_timeOffset;
  TReportReturn objTReportReturn = new TReportReturn();
  objTReportReturn.ReportColumns = await new ReportsEntityContext().GetTechniciansReportColumns<AdminTechnicianReportInput>(input, sync);
  objTReportReturn.ReportSettings = await new ReportsEntityContext().GetGeneralSettingsData<AdminTechnicianReportInput>(input, sync);
  objTReportReturn.ReportData = await new ReportsDbContext().GetUserListDynamic<AdminTechnicianReportInput>(input, sync);
  return objTReportReturn;
}

private Task<Utils.TReportReturn> GetReportDataColumnSettingsAsync(AdminTechnicianReportInput input)
{ return DoGetReportDataColumnSettingsAsync(input, sync: false); }
private Utils.TReportReturn GetReportDataColumnSettings(AdminTechnicianReportInput input)
{ return DoGetReportDataColumnSettingsAsync(input, sync: true).GetAwaiter().GetResult(); }

The key with this pattern is that any method taking a sync parameter must return a completed task when that argument is set to true.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.