C# 异步等待和任务运行问题

C# 异步等待和任务运行问题,c#,multithreading,task,C#,Multithreading,Task,我需要知道这些记录有什么不同,如果有,它们是什么? 这对我来说很难: 1) Task.Run(async () => { await CheckVerification(); }); 2) Task.Run(() => CheckVerification()); 3) await Task.Run(async () => { await CheckVerification(); }); 1) 开始一项任务。该任务将在中异步等待该方法,因此您的UI或调用线程不会阻塞 2) 启动

我需要知道这些记录有什么不同,如果有,它们是什么? 这对我来说很难:

1) Task.Run(async () => { await CheckVerification(); });
2) Task.Run(() => CheckVerification());
3) await Task.Run(async () => { await CheckVerification(); });
1) 开始一项任务。该任务将在中异步等待该方法,因此您的UI或调用线程不会阻塞

2) 启动一项任务,这将启动另一项任务。一切都是异步运行的,没有什么等待的,完全启动并忘记


3) 将启动一个任务,该任务启动一个方法并等待它,返回执行上下文,让调用线程将执行上下文与其等待一起释放,让调用此方法的方法继续执行,直到等待此方法。

如果我们忘记
任务,可能更容易理解差异。请运行一秒钟。第一点和第二点之间的差异基本上与等待或仅从
任务返回内部任务的方法相同:

// 1)
public async Task WithAwait() => await SomeOtherTaskReturningMethod();

// 2)
public Task WithoutAwait() => return SomeOtherTaskReturningMethod();
第一个方法创建另一个任务,它封装了内部任务,这是一个很小的开销,但是这两个方法在功能上几乎相同。一个小的区别是当
SomeOtherTaskReturningMethod
抛出异常时,内部任务的
AggregatedException
将被展开,并且(第一个)内部异常将被进一步抛出。当然,事情仍然取决于外部任务发生了什么。在您的第三点中,它也在等待,因此您将从外部任务(如果有)中获得未包装的异常,而第一个和第二个示例只是fire and forget

现在让我们考虑<代码>任务。再次运行< /代码>。主要的问题是,当您也可以简单地调用

wait CheckVerification()时,为什么这个方法有重载,它接受
任务
s(实际上是
任务
返回回调)并得到相同的结果?(我知道这不是问题的一部分,但可能值得澄清)

因此,存在这种
Task.Run
重载的原因是
Task
返回方法本身不一定在另一个线程上执行(我建议)。例如,它可以通过网络套接字发送消息并返回一个
任务
,该任务将在收到特定答案时完成。这使得操作是异步的,仍然不是多线程的

如果您有这样一个任务,并且希望强制它在另一个线程上执行,那么您可以通过
task.Run
执行它,它使用默认的调度程序并最终在池线程上执行您的任务

但值得一提的是,这是一种非常罕见的情况。在大多数情况下,您应该依赖于
任务
返回方法的内部实现

TL;医生:

所以我认为真正的问题是

await CheckVerification();


是更好的解决方案(或者可能是其中一个没有
等待
,即触发并忘记模式)。在大多数情况下,我会投票支持第一个选项,但如果您确实确信
CheckVerification
返回的任务必须分配给池线程(无论它是否在池线程中),那么第二个选项也可以被证明是正确的。

FYI:这些选项都不正确。最常用的方法是使用
wait CheckVerification(),在某些特殊情况下,
等待任务。运行(()=>CheckVerification())@CamiloTerevinto。你好如果我不想等待结果。我只需要创建任务并为用户返回OK。这项任务的工作原理与后台任务类似?那么您只需要
检查验证()
,这是唯一正确的发射并忘记选项。您认为他们每个人都做什么?您知道在这些表达式中执行的每个底层操作都在做什么吗?如果没有,您不了解哪些内容?你有没有研究过每一种操作是什么,它们是做什么的?在那项研究中,你有什么不理解、困惑或矛盾的地方?所有这些方法都会产生一个额外的、不必要的任务。使用
Task.Run
仅用于CPU限制的工作。1和2都是完全触发并忘记操作所有表达式都是异步的,因此#1没有描述任何事物之间的差异,它适用于所有事物。如前所述,#2并不是列出的唯一一个免责选项#3,这里没有列出的每个选项之间也有许多不同之处。
await Task.Run(() => CheckVerification());