我正在尝试为我的项目中已经存在的代码创建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 task
和Insert()
方法将以下代码实现为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.");
}
}
}
如果需要使问题更加准确和易于理解,我会很乐意添加更多内容。
答案 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;
}
}