【问题标题】:Asynchronously Running Synchronous Code异步运行同步代码
【发布时间】:2016-07-14 23:26:56
【问题描述】:

实体框架将存储过程作为 DbContext 类的方法导入。 但是,它们不是异步的,我希望能够从异步 WebApi 控制器调用它们而不会阻塞线程。我已经编写了一个异步包装器方法,但我对 Visual Studio 给我的警告感到困惑。

这段代码会异步执行吗?

    public async Task AttachTypeToMeetingTime(int meetingTimeId,int meetingTypeId)
    {
        await Task.Run(() =>
        {
            //synchronous method generated by EF.
            //VS warning here
            AttachTypeToMeetingTime(meetingTimeId, meetingTypeId);
        });
    }

Visual Studio 给了我警告:

因为没有等待这个调用,所以在调用完成之前当前线程的执行继续

但是,如果我按照建议添加等待,它会以红色下划线显示,并且不会编译。

我不希望当前线程在调用完成之前继续吗?

【问题讨论】:

  • 旁注:我希望您了解您实际尝试做的事情只会降低性能 - 您现在不是从线程池处理请求中获得一个线程,而是将工作转移到另一个线程池线程并支付上下文切换费用/线程同步(此外线程也没有设置文化/当前请求,以后会给你各种乐趣)
  • @AlexeiLevenkov 对不起,我以前见过,我认为没问题。将解决方案部分移至自己的答案。我所做的与异步控制器方法和/或像 FindAsync() 这样的普通 EF 异步方法有何不同?
  • 真正的异步方法不会在线程上忙等待(与同步一次不同)。您可能想了解一般的异步,Should I expose asynchronous wrappers for synchronous methods? 是一个起点。

标签: c# entity-framework lambda async-await task


【解决方案1】:

您正在进行递归调用。我不认为你打算这样做。

它应该像你说的那样调用同步方法,而不是 AttachTypeToMeetingTime

public async Task AttachTypeToMeetingTime(int meetingTimeId,int meetingTypeId)
{
   await Task.Run(() =>
   {
      SomeMethod(meetingTimeId, meetingTypeId);
        ^^^^^
   });
}

【讨论】:

  • 很好的递归
  • 这是一个错字,感谢您发现。我编辑了问题。
【解决方案2】:

我错误地调用了方法名称。应该是:

public async Task AttachTypeToMeetingTimeAsync(int meetingTimeId,int meetingTypeId)
    {
        await Task.Run(() =>
        {
            //synchronous method generated by EF.
            //VS warning here
            AttachTypeToMeetingTime(meetingTimeId, meetingTypeId);
        });
    }

生成方法的签名是

AttachTypeToMeetingTime(int? meetingTimeId,int? meetingTypeId)

我认为因为我的方法的参数是 int 而生成的方法的参数是 int?,所以签名不会发生冲突,但我想这会绊倒 Visual Studio 的建议引擎,也许编译器。

【讨论】:

    【解决方案3】:

    在下面的代码中填写以“Your”开头的内容。

    public async Task AttachTypeToMeetingTime(int meetingTimeId,int meetingTypeId)
    {
       using(var context = new YourContext())
       {
          await conext.Database.ExecuteSqlCommandAsync("YourStoredProcedureName @YourParam1Name, @YourParam2Name", meetingTimeId, meetingTypeId);
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      • 2020-12-31
      相关资源
      最近更新 更多