【问题标题】:call async method from non async mvc controller and get return to a variable从非异步 mvc 控制器调用异步方法并返回到变量
【发布时间】:2016-08-25 05:33:01
【问题描述】:
   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();
    }

}

GetReportDataColumnSettings 函数调用许多异步方法,即模型库 dll。

HomeController 中的 Index() 方法是一个 mvc 方法,我想在 result 变量中获取返回值。 Itried getawaiter().getmethod(),但没有成功。

我不喜欢将 Index() 方法更改为异步任务。请提出另一种获得结果的方法

【问题讨论】:

    标签: asp.net-mvc asynchronous methods controller call


    【解决方案1】:

    我不喜欢将 Index() 方法更改为异步任务。

    为什么不呢?这是迄今为止最简单、最正确的解决方案。

    第二个最简单的方法是让一切同步。也就是说,如果你不去async all the way,那就一路同步吧。

    有多种从同步代码中调用异步的技巧,这些技巧在您的情况下可能有效,也可能无效;这些黑客在任何地方都不起作用。更多详情请看我的async brownfield article

    就您而言,您最初的尝试是使用 Blocking Hack。为了在预 Core ASP.NET 上正常工作,您必须为整个方法调用树中的每个 await 使用 ConfigureAwait(false)。这通常是可能的(当然,并不总是可能的,因为库代码可能会或可能不会使用它),但它会导致维护问题(忘记一个,并且您会遇到可能以死锁结束的竞争条件)。我在我的博客上详细解释了why the deadlock happens

    如果你不会一直异步,如果你不能一直同步,那么我推荐 Boolean Sync Argument Hack,它需要整个调用堆栈同时支持同步 异步调用者。您发布的代码看起来像这样:

    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(); }
    

    这种模式的关键是任何采用sync 参数的方法都必须在该参数设置为true 时返回已完成的任务。

    【讨论】:

      猜你喜欢
      • 2014-07-14
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-22
      • 2016-07-20
      相关资源
      最近更新 更多