如何在存储库中创建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)
{
...
}
}
答案 0 :(得分:1)
使用async / await仅在函数是异步的情况下才有用,并且您希望调用函数的客户端是异步的(以及它们的客户端等)。
原因是,因为调用异步函数并不意味着执行该函数。这意味着任务被安排运行由可用线程池中的线程执行的功能。在安排任务后,您的函数可以继续下一个语句。当需要计划任务的结果时,它等待计划任务完成。
上面开始一个线程的优点是,这可以节省开始新线程的开销,并在之后进行清理。缺点是您在安排任务时不确定线程是否可用。
如果您的函数未声明为异步,您仍然可以使用Task.Run(()=> OtherFunction(...))安排任务,但您无法等待它。要等待任务完成,您必须调用Task.Wait(...)。与此同时,调用函数的线程无法继续。如果此线程是UI线程,您会注意到这一点,因为您的UI没有响应。
因此,如果您想正确使用其他异步函数,最好将函数声明为异步并返回Task而不是void和Task <TResult
&gt;而不是TResult。在返回之前调用另一个异步函数,执行其他操作并等待任务。客户端需要异步并返回任务/任务<TResult
&gt;。可能返回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));
}
如果您不想强制客户端异步,请考虑创建两个版本,一个是异步,另一个是非异步。这很常见。请参阅文件,流,Db连接等中的定义。