我正在努力了解 async/await 并认为我确实了解有关用法的一些事情。但仍然不太清楚在下面的场景中实际好处是什么。
查看 Task.Run 用法。第一种方法使用普通委托(delegate)并使用 Thread.Sleep,但第二种方法使用“异步”委托(delegate)和 Task.Delay。
我的问题是:这对这个方法有什么影响(或没有影响)?
该方法本身是一个异步方法。该代码正在创建一个单独的线程(通过 Task.Run),并且该线程除了执行该委托(delegate)之外别无他法。因此,即使它在 Task.Delay 上产生等待,在这种情况下有什么用,因为线程无论如何都是一个孤立的线程,不用于任何其他事情,即使它只使用 Thread.Sleep,线程仍然会上下文切换到处理器的其他线程。
// The task thread uses a async delegate
public async Task RetrySendEmail(MailMessage message)
{
bool emailSent = false;
await (Task.Run(***async ()*** =>
{
for (int i = 0; i < 3; i++)
{
if (emailSent)
phá vỡ;
khác
// Wait for 5 secs before trying again
***await Task.Delay(5000);***
thử
{
Smtphost.Send(message);
emailSent = true;
phá vỡ;
}
catch (Exception e) { emailSent = false; // log; }
}
return emailSent;
}));
}
// The task thread uses a normal delegate
public async Task RetrySendEmail(MailMessage message)
{
bool emailSent = false;
await (Task.Run(***()*** =>
{
for (int i = 0; i < 3; i++)
{
if (emailSent)
phá vỡ;
khác
// Wait for 5 secs before trying again
***Thread.Sleep(5000);***
thử
{
Smtphost.Send(message);
emailSent = true;
phá vỡ;
}
catch (Exception e){ emailSent = false; // log; }
}
return emailSent;
}));
}
My question is : how does this make any difference to this method (or it does not) ?
两个不同点
- sử dụng
async
内部代表Task.Run
意味着你实际上运行了一个 Task
. Task.Run
这对你是隐藏的是异步感知并为你解开内部任务,这是Task.Factory.StartNew
没有做
当您使用带有 Task.Run
的异步委托(delegate)时,您创建一个新线程,然后在您点击 await Task.Delay
后放弃控制权.延续将在任意线程池线程上运行。此外,委托(delegate)由编译器转换为状态机。
使用普通委托(delegate),您创建一个线程,同步阻塞它 5 秒,然后从您离开的地方继续。没有状态机,没有屈服。
So, even if it yields with an await on Task.Delay, what is the use in this scenario, since the thread is anyways a isolated thread not used for anything else and even if it just uses Thread.Sleep, the thread would still context switch to yield to other threads for the processor.
async
的使用与 Task.Run
可以在您想要同时执行 CPU 和 IO 绑定(bind)工作时,全部在专用线程中进行。您的想法是正确的,在异步委托(delegate)产生之后,它会在任意线程上返回。不过,如果你没有使用 Task.Run
, 和 async
从附加了自定义同步上下文(例如 WinformsSynchronizationContext)的线程执行的方法,await
之后的任何工作将返回到 UI 消息循环,除非你使用 ConfigureAwait(false)
.
说实话,Task.Run
的场景我还没见过多少和 async
正确使用。但有时它确实有意义。
Tôi là một lập trình viên xuất sắc, rất giỏi!