如何使用 EF 6 将以下用于数据库连接的代码转换为 C# 中的异步任务?

How to convert below code used for the database connection using EF 6 to async task in C#?

我正在尝试使用 EF 6 为我项目中已有的数据库连接代码创建 async task

我已经创建了异步任务并且它工作正常,您可以参考 Using Async Task 部分的代码。但我想将 The existing code of the project 部分重写为 async task 以保持项目中的一致性。

使用异步任务:下面的代码工作正常。

public static async Task<Student> InsertAsync(Student student)
{
  try
  {
    using(PracticeContext context = new PracticeContext())
    {
      Repository<Student> repository = new Repository<Student>(context);
      return await repository.InsertAsync(student);
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex);
    return null;
  }
}

项目现有代码:

我想为 Insert()Execute() 方法将下面的代码实现为 async task。因此,数据将被添加到 database 而无需长时间持有 UI 并使项目更加用户友好。

请建议或提供以下代码的async implementation

public static Student Insert(Student student)
{
  try
  {
    return Execute<Student, Student>((repository) => {
      return repository.Insert(student);
    });
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex);
    return null;
  }
}

private static TResult Execute<TResult, T>(Func<Repository<T>, TResult> func) where T: class
{
  using(PracticeContext context = new PracticeContext())
  {
    try
    {
      return func(new Repository<T>(context));
    }
    catch(Exception ex)
    {
      Console.WriteLine(ex);
      throw new Exception("Error Occured.");
    }
  }
}

如果需要,我很乐意添加更多内容以使问题更加准确和易于理解。

您要做的第一件事是更改 lowest-level 调用以使用异步版本并在其封闭的 method/lambda 中使用 async。然后让 async 从那里增长。所以第一步是:

    return Execute<Student, Student>(async (repository) => {
      return await repository.Insert(student);
    });

此代码要求 Execute 允许 asynchronous delegates。在这一步,我们可能希望其他代码继续使用同步 Execute,因此我们可以 copy/paste 它并使新的重载采用异步委托:

private static async Task<TResult> Execute<TResult, T>(Func<Repository<T>, Task<TResult>> func) where T: class
{
  using(PracticeContext context = new PracticeContext())
  {
    try
    {
      return await func(new Repository<T>(context));
    }
    catch(Exception ex)
    {
      Console.WriteLine(ex);
      throw new Exception("Error Occured.");
    }
  }
}

既然异步Executereturns一个Task<T>,那么我们就需要await把它返回到调用方法中:

    return await Execute<Student, Student>(async (repository) => {
      return await repository.Insert(student);
    });

这也会使调用方法异步:

public static async Task<Student> InsertAsync(Student student)
{
  try
  {
    return await Execute<Student, Student>(async (repository) => {
      return await repository.Insert(student);
    });
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex);
    return null;
  }
}