我们可以从构造函数中调用异步方法吗?

Hoc*_*Lim 3 c#

我需要从 mvc 应用程序调用第三方异步方法。此异步方法的名称是 ForceClient.QueryAsync。它来自一个开源项目:https ://github.com/developerforce/Force.com-Toolkit-for-NET/ 。

下面工作正常,当进程处于 mvc 的 View 阶段时, model.Opportunity 包含预期信息:

public async Task<ActionResult> MyController(string Id) {
    . . . .
    MyModel model = new MyModel();
    var client = new ForceClient(instanceUrl, accessToken, apiVersion);
    var qry = await client.QueryAsync<MyModel.SFOpportunity>(
            "SELECT Name, StageName FROM Opportunity where  Id='" + Id + "'");
    model.Opportunity = qry.Records.FirstOrDefault();
    . . . .
return View(viewName, myModel);
}
Run Code Online (Sandbox Code Playgroud)

但下面不起作用。当流程处于View阶段时,model.Opportunity为null。我做了一些调试,发现流程是这样的:

1)步骤1

2)步骤2

3)在View阶段。此时 model.Opportunity 为 null,我需要将其填充。

4)步骤3。

public async Task<ActionResult> MyController(string Id) {
    . . . .
    MyModel myModel = await Task.Run(() =>
        {
            var result = new MyModel(Id);
            return result;

        });   // =====> Step 1
    . . . .
return View(viewName, myInfoView);
}    

public class MyModel
{
    public SFOpportunity Opportunity { get; set; }
    public MyModel(string id)
    {
        setOpportunityAsync(id);
    }

    private async void setOpportunityAsync(string id)
    {
        . . .
        var client = new ForceClient(instanceUrl, accessToken, apiVersion);
        var qry = await client.QueryAsync<MyModel.SFOpportunity>(
             "SELECT Name, StageName FROM Opportunity where  Id='" + id + "'");  // ======>  Step2 
        Opportunity = qry.Records.FirstOrDefault();  // =====> step3
    }
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是我需要做什么才能让它按以下顺序执行步骤:1)第 1 步

2)步骤2

3)步骤3

4)在View阶段。此时应该填充 model.Opportunity。

Ste*_*ary 8

你不能有async构造函数。

一种替代方法是使用async工厂方法

public class MyModel
{
  public SFOpportunity Opportunity { get; set; }
  private MyModel() { }

  public static async Task<MyModel> CreateAsync(string id)
  {
    var result = new MyModel();
    await result.setOpportunityAsync(id);
    return result;
  }

  private async Task setOpportunityAsync(string id)
  {
    ...
  }
}

Run Code Online (Sandbox Code Playgroud)