【问题标题】:HOWTO: Convert Task<MyBoolResult> into MyBoolResult class object如何:将 Task<MyBook Result> 转换为 MyBook Result 类对象
【发布时间】:2021-03-14 18:49:31
【问题描述】:

我有一个 ASP.NET MVC 应用程序,它正在调用 WEB API REST 服务方法。

如果操作成功与否,我正在使用自定义 MyBoolResult 对象返回。这是一个具有一些构造函数和属性的类。

现在我正在尝试在 DoWork 方法中将 Task 转换为 MyBoolResult。我怎样才能做到这一点?

下面的代码sn-p:

public MyBoolResult DoWork()
{
        string requestUri = "api/MyController/CreateFile";
        CustomObject myParams = new CustomObject();

        // Below line does not work. How can I convert the returned object into MyBoolResult?
        MyBoolResult myBoolObject = this.CreateFile(requestUri, myParams);

        return myBoolObject;
}

public async Task<MyBoolResult> CreateFile(string requestUri)
{
     // Here some stuff and initializations
     // To simplify I am not putting here all the code previous to PostAsync

     HttpResponseMessage res = await client.PostAsync(requestUri, httpContent);
     if (res.IsSuccessStatusCode)
     {
         var webApiResp = res.Content.ReadAsStringAsync().Result;
         result = Newtonsoft.Json.JsonConvert.DeserializeObject<MyBoolResult>(webApiResp);
     }
     else
     {
         result = MyBoolResult.ToErrorResult(String.Format("An error occurred! HTTP error code {0}", res.StatusCode));
     }

     return result;
}

【问题讨论】:

    标签: c# asp.net-mvc asp.net-web-api async-await asp.net-web-api2


    【解决方案1】:
    MyBoolResult myBoolObject = await this.CreateFile(requestUri, myParams);
    

    DoWork 需要更改为异步。或者,您可以在 createfile 调用中使用 .Result,但对于潜在的死锁问题,我不建议这样做。

    【讨论】:

      【解决方案2】:

      DoWork 也需要异步。否则执行将跳过该代码。那样异步有点传染性。

      public async Task<MyBoolResult> DoWork()
      {
          string requestUri = "api/MyController/CreateFile";
          CustomObject myParams = new CustomObject();
      
          // Below line does not work. How can I convert the returned object into 
          MyBoolResult?
          MyBoolResult myBoolObject = await this.CreateFile(requestUri, myParams);
      
          return myBoolObject;
      }
      

      Task 确实有一个 result 属性,但您需要调用 Task.Wait() 这将锁定调用线程并破坏使用异步的目的。

      【讨论】:

      • 但是调用 DoWork 的方法也需要异步。如果我尝试这样做,则使用该方法: MyBoolResult res = DoWork();然后我得到错误:无法将类型'System.Threading.Tasks.Task'隐式转换为'MyBoolResult'
      • 是的,异步具有传染性的趋势。在顶层通常有一个按钮调用或启动工作的东西。这个顶层不应该依赖于异步方法的结果,只需启动它并继续。或者你会有一个方法存根async void SomeCall().如果你的整个过程依赖于工作的结果并且在它完成之前不能做任何其他事情,那么我会考虑不使用异步。
      • 是的,我明白了,这具有传染性,链中的所有方法调用都必须是 async-await 才能使代码“同步”,我的意思是,等待被调用的方法完成并完成。是的,我在顶层有一个按钮调用。当在我的 asp.net mvc 视图中按下按钮时,从 javascript 中,我使用 jquery $.ajax(....) 进行异步调用。这会在控制器中调用一个操作,所以我知道我必须将第一个操作方法标记为异步,并在其中放置一个等待,以此类推,直到到达调用 web api REST 的最后一个方法。我说的对吗?
      • @Ralph 是的,您的控制器操作也需要异步。此外,所有异步方法都需要返回一个任务(永远不要这样做async void),并且您不应在任务上调用 Wait() 或 Result。
      猜你喜欢
      • 2019-08-07
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多