存储库中的异步/等待
本文关键字:等待 异步 存储 | 更新日期: 2023-09-27 18:27:09
如何在存储库中创建async/await方法?我应该使用Task.Run吗?
public virtual void Add(T entity)
{
try
{
if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
_context.Entry(entity);
Entities.Add(entity);
}
catch (DbEntityValidationException dbEx)
{
...
}
}
只有当你的函数是异步的,并且你期望调用你的函数的客户端是异步的(以及他们的客户端等)时,使用async/await才有用。
原因是,因为调用异步函数并不意味着执行了该函数。这意味着任务被安排运行可用线程池中的线程执行的函数。安排任务后,您的功能可以继续执行下一条语句。当它需要计划任务的结果时,它会等待,直到计划任务完成。
与自己启动线程相比,这样做的好处是节省了启动新线程和随后进行清理的开销。缺点是,在安排任务时,您不确定线程是否可用。
如果你的函数没有声明为async,你仍然可以使用task.Run(()=>OtherFunction(…))调度任务,但你不能等待它。要等待任务完成,你必须调用task.wait(…)。与此同时,调用你的函数的线程无法继续。如果这个线程是UI线程,你会注意到这一点,因为你的UI没有响应。
因此,如果你想正确使用其他异步函数,最好声明你的函数为async,并返回Task而不是void,返回Task <TResult
>而不是TResult。调用另一个异步函数,做其他事情,等待任务返回。客户端需要是异步的,并返回Task/Task <TResult
>。唯一可能返回void的异步客户端是事件处理程序。
示例:
public async void button1_clicked(object sender, ...)
{
Task<int> task1 = this.DoSomethingAsync(...);
// while task1 is running you can do other things
// you can even schedule another task:
Task task2 = this.DoSomethingElseAsync(...);
// do other things. After a while you need the result of task1:
int task1Result = await task1;
// or if you want to await until both tasks are finished:
await Task.WhenAll(new Task[]{task1, task2});
int task1Result = task1.Result;
}
private async Task<int> DoSomethingAsync(...)
{
// schedule another async task and await:
await DoSomethingElseAsync(...);
return 42;
}
private async Task DoSomethingElseAsync(...)
{
// do something really important:
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
}
如果不想强制客户端异步,可以考虑创建两个版本,一个是异步版本,另一个是非异步版本。这很常见。请参阅文件、流、数据库连接等中的定义。