代码之家  ›  专栏  ›  技术社区  ›  monty

从同步控制器方法到异步控制器方法的正确转换(使用void时)

  •  0
  • monty  · 技术社区  · 8 年前

    使用实体框架核心2.0和。NET Core 2.0 Web API控制器我正在尝试将它们从同步方法重写为异步方法。

    这实际上对于我的控制器方法来说很容易,只需查询数据。

    不幸的是,我将DbContext方法SaveChanges包装到一些助手方法中,用于集中记录数据库更改。

    在这里,我开始思考如何在异步上下文中正确使用void的组合。

    代码说明: MyController是一个web api控制器。PostMethod是一种(当前)同步post方法,它接收请求模型,处理它,进行更改,然后保存更改。

    控制器中的SaveChangesWithLogs调用扩展方法并打印返回的日志。

    扩展方法SaveChangesWithLogs生成日志条目(一些保存前,一些保存后),执行实际保存并返回日志。

    
      public class MyController : BaseController 
      {
    
        [HttpPost]
        public IActionResult PostMethod([FromBody]PostRequestModel request)
        {
            //do something
            SaveChangesWithLogs();
            //return created at
        }
    
        protected void SaveChangesWithLogs()
        {
          List logs = DbContext.SaveChangesWithLogs();
          foreach (string log in logs)
          {
            LogInfo(log); //just prints the generated logs
          }
        }
    
      }
    
      public static class MyExtensionMethod 
      {
    
        public static List SaveChangesWithLogs(this DbContext dbContext)
        {
          List logs = null;
          //pre-save prepare logs
          dbContext.SaveChanges();
          //post-save modifications of logs
          return logs;
        }
      }
    

    在关于异步编程的教程中,他们提到方法应该一直是异步的。

    所以我的问题是: SaveChangesWithLogs方法的(方法签名)是什么样子的?

    
      public class MyController2 : BaseController 
      {
    
        [HttpPost]
        public async Task PostMethod([FromBody]PostRequestModel request)
        {
            //do something
            await SaveChangesWithLogs();
            //return created at
        }
    
        //does a correct implementation need async here too?
        protected void SaveChangesWithLogs()
        {
          List logs = await DbContext.SaveChangesWithLogs();
          foreach (string log in logs)
          {
            LogInfo(log); //just prints the generated logs
          }
    
          //return what???
        }
    
      }
    
      public static class MyExtensionMethod2 
      {
    
        public static async Task> SaveChangesWithLogs(this DbContext dbContext)
        {
          List logs = null;
          //pre-save prepare logs
          await dbContext.SaveChanges();
          //post-save modifications of logs
          return logs;
        }
      }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Archlight    8 年前

    您只需像以前一样使用返回类型并围绕它包装任务。没有比这更神奇的了。

    我猜您的列表类型属于某种类型,并添加了该类型以用于显示。

    protected async Task<bool> SaveChangesWithLogs()
        {
          List logs = await DbContext.SaveChangesWithLogs();
          foreach (string log in logs)
          {
            LogInfo(log); //just prints the generated logs
          }      
          return true;
        }
    
    public static async Task<List<myLogType>> SaveChangesWithLogs(this DbContext dbContext)
    {
        List<myLogType> logs = null;
        //pre-save prepare logs
        await dbContext.SaveChanges();
        //post-save modifications of logs
        return logs;
    }
    
    推荐文章