gpt4 book ai didi

c# - 使用和不使用 await 运算符的任务执行

转载 作者:行者123 更新时间:2023-11-30 12:22:37 26 4
gpt4 key购买 nike

我问了一个question昨天,答案很好。但现在我正试图了解 await 的作用以及任务执行的工作原理。

我读过有关 await 的文章:await 运算符应用于异步方法中的任务,以暂停该方法的执行,直到等待的任务完成。该任务代表正在进行的工作(来自 msdn 站点)。

Task.run:Run 方法允许您在单个方法调用中创建和执行任务,并且是 StartNew 方法(来自 msdn 站点)的更简单替代方法。

现在,使用代码:

        public async Task YourFunc()
{
Exception error = null;
try
{
var task = Task.Run(() =>
{
Thread.Sleep(3000);
throw new ArgumentException("test argument exception");
});
var completed = task.IsCompleted;
var faulted = task.IsFaulted;
Console.WriteLine(completed);
Console.WriteLine(faulted);
}
catch (Exception ex)
{
error = ex;
}
this.MigrationProcessCompleted(error);
}

我删除了 await 运算符,并在行 Console.WriteLine(completed); 上设置了一个断点。为什么在此断点等待2-3分钟后,任务仍未完成且未出现故障?我在任务的代码中设置了一个断点并抛出异常,因此任务必须至少标记为错误或已完成...

最佳答案

没有人真正回答你的问题。如果您等待超过 3 秒,您有合理的期望看到 task.isCompletedtask.isFaulted 为真。

您的期望没有错。这里的问题只是调试器是如何工作的。当您在该断点处停止等待时,所有其他线程也停止了,因此没有任何进展并且尚未抛出异常。

这只是调试的一个怪癖,如果你想看到你期望的结果,你有几个选择:

  1. 卡住线程而不是使用断点。为此,请在 var task=Task.Run() 之后放置一个断点,然后在调试器中打开“线程”窗口。找到当前线程(带有黄色箭头)右键单击它并选择“卡住”,然后按 F8 或单击继续让应用程序继续运行。 3-4 秒后,单击调试器上的“暂停”按钮,再次双击卡住的线程。您现在可以检查 task.IsCompletedtask.IsFaulted 的值,它们应该为真。
  2. 在检查任务之前添加超时:

代码:

var task = Task.Run(() =>{
Thread.Sleep(3000);
throw new ArgumentException("test argument exception");
});
Thread.Sleep(5000);
var completed = task.IsCompleted;
var faulted = task.IsFaulted;
Console.WriteLine("Completed ::" + completed);
Console.WriteLine("Faulted ::" + faulted);

现在您可以在 Thread.Sleep(5000) 之后放置一个断点并确认任务已出错/已完成。

请记住,正如其他人所说,立即等待 Task.Run() 的用例几乎总是错误的。请记住,async/await 的全部意义在于释放当前线程,使其不会进行无用的等待。如果你执行一个 Task.Run 然后执行一个 await 你没有取得任何成就,因为你只是释放当前线程(将它放回线程池中)但是Task.Run() 将从线程池中占用一个线程。从概念上讲,您所做的一切都是将您的工作从一个线程 ID 转移到另一个线程 ID,而没有真正的 yield (即使您的 Task.Run 中的工作受 CPU 限制)。

在这种情况下,您最好根本不执行 Task.Run,而只是在当前线程上同步执行工作。

关于c# - 使用和不使用 await 运算符的任务执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40301882/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com