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

时间:2019-06-12 12:02:20

标签: c# async-await entity-framework-6

我正在尝试为我的项目中已经存在的代码创建async task,以使用EF 6建立数据库连接。

我已经创建了一个异步任务,它可以正常工作,您可以参考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;
  }
}

项目的现有代码:

我想为async taskInsert()方法将以下代码实现为Execute()。因此,无需长时间保持UI就可以将数据添加到database中,并使项目更加用户友好。

请建议或提供以下代码中的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.");
    }
  }
}

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

1 个答案:

答案 0 :(得分:2)

您要做的第一件事是将最低级别的调用更改为使用异步版本,并在其封装方法/ lambda中使用async。然后让async从那里成长。因此第一步将是:

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

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

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.");
    }
  }
}

现在异步Execute返回一个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;
  }
}