- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在运行以下代码(C#7.1 控制台应用程序),但我无法真正理解行为差异的原因。
如果我等待常规异步方法调用或 Task.Run - 它会按预期工作(即应用程序不会立即返回)。但是,如果我使用 Task.Factory.StartNew - 它会立即返回,而无需实际运行代码。
奇怪的是 - 如果我使用 StartNew 但在方法内部删除 await,它不会立即返回......
问题:这会立即返回:
static async Task Main(string[] args)
{
await Task.Factory.StartNew(DisplayCurrentInfo);
}
static async Task DisplayCurrentInfo()
{
await WaitAndApologize();
Console.WriteLine($"The current time is {DateTime.Now.TimeOfDay:t}");
Thread.Sleep(3000);
}
即- 我看不到任何打印到控制台的内容,并且控制台已经关闭。
没问题:这不会立即返回:
static async Task Main(string[] args)
{
await DisplayCurrentInfo(); // or await Task.Run(DisplayCurrentInfo);
}
static async Task DisplayCurrentInfo()
{
await WaitAndApologize();
Console.WriteLine($"The current time is {DateTime.Now.TimeOfDay:t}");
Thread.Sleep(3000);
}
奇怪:这也不会立即返回:
static async Task Main(string[] args)
{
await Task.Factory.StartNew(DisplayCurrentInfo);
}
static async Task DisplayCurrentInfo()
{
WaitAndApologize();
Console.WriteLine($"The current time is {DateTime.Now.TimeOfDay:t}");
Thread.Sleep(3000);
}
等待并道歉:
static async Task WaitAndApologize()
{
// Task.Delay is a placeholder for actual work.
await Task.Delay(2000);
// Task.Delay delays the following line by two seconds.
Console.WriteLine("\nSorry for the delay. . . .\n");
}
最佳答案
如果您使用 Task.Factory.StartNew(MethodThatReturnsTask)
你会得到一个 Task<Task<T>>
或 Task<Task>
取决于该方法是否返回通用任务。
最终结果是你有 2 个任务:
Task.Factory.StartNew
生成一个调用 MethodThatReturnsTask
的任务, 让我们称这个任务为“任务 A”MethodThatReturnsTask
在你的情况下返回 Task
,我们称之为“任务 B”,这意味着 StartNew
的过载使用处理此问题的,最终结果是您返回包装任务 B 的任务 A。“正确”等待这些任务需要 2 个等待,而不是 1 个。您的单个等待只是等待任务 A,这意味着当它返回时,任务 B 仍在执行等待完成。
要天真地回答您的问题,请使用 2 个等待:
await await Task.Factory.StartNew(DisplayCurrentInfo);
但是,值得怀疑的是,为什么您需要生成一个任务来启动另一个异步方法。相反,你最好使用第二种语法,你只需等待方法:
await DisplayCurrentInfo();
意见如下:一般来说,一旦您开始编写异步代码,使用 Task.Factory.StartNew
或其任何同级方法应保留,以便在您需要生成一个线程(或类似的东西)来调用非异步的东西时使用。如果您不需要此特定模式,最好不要使用它。
关于c# - 在方法上使用 await Task.Factory.StartNew 将立即返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50982505/
按照MSDN Documentation TaskFactory.StartNew,它创建并启动一个任务。因此,对于以下代码示例 class Program { public static v
当这段代码运行时,我无法在我的 UI 中移动或做任何事情: var a = txtLot.Text; var b = cmbMcu.SelectedItem.ToString(); var c = c
如果我将使用 TaskFactory.StartNew(MyFunc(), new CancellationToken(), TaskCreationOptions.None, TaskSchedul
至少当我在代码中实现它时,我必须修改 StartNew Task 才能获得相同的行为。在我的 View 中有一个开始按钮。它的 IsEnabled 属性绑定(bind)到 View 模型中的 bool
我什至不假装理解 C# 中的线程,所以我正在寻找关于线程的真正简单的解释 - 更具体地说是 .NET 4 中的 StartNew() 功能。 我使用以下代码以一种即发即弃的方法调用另一个方法。当网页需
我有这个简单的函数,作为一项任务,它只打印数据集的值。我从主函数和索引传递数据集。问题是我只填充了 2 个数据集索引,但是该函数总是向前跳一个,即在最后一次迭代中它想要开始读取索引 2,该索引未初始化
这是我的代码顺序: 我做了很多 task.factory.startnew(()=> myFunction(myObject, httpSessionState)) 我将 System.Web.Ses
我有 2 个线程调用“Task.Factory.StartNew”。假设一个线程 (ThreadA) 比另一个线程 (ThreadB) 稍微领先。 ... 在线程 A 中,稍微提前调用 Task.Ru
我正在尝试重构一些代码以通过并行性实现更高的吞吐量。我进行了所有基础重构,以实现线程安全的极简主义单一调用。我的方法采用多个参数: private Domain ImportDomain(Constr
我正在从一个函数开始一个新任务,但我不希望它在同一个线程上运行。我不关心它在哪个线程上运行,只要它是不同的线程即可(因此 this question 中提供的信息没有帮助)。 我能保证下面的代码在允许
我想找出为什么需要阻止以下内容才能让控制台写入: Task.Factory.StartNew(() => Console.WriteLine("KO"), TaskCreationOptions.Lo
我得到了以下方法,我想传递 dosleep 方法的返回值: static void Main(string[] args) { var t1 = Task.Factory.StartNew((
我正在尝试掌握 .NET 中的多线程编程。 我想在一个 for 循环中创建 100 个任务,每个任务会休眠 1 秒,然后输出创建时使用的 i 和它的托管线程 ID。所有任务完成后,我想输出经过的总时间
我知道 TPL 不一定为并行集中的每个任务创建一个新线程,但它总是至少创建一个线程吗?例如: private void MyFunc() { Task.Factory.StartNew(()
我正在使用 Task.Factory.StartNew 使长时间的处理服务调用脱离 UI 线程。但是,我在加载应用程序后立即收到以下异常, 通过等待任务或访问其 Exception 属性未观察到任务的
我是 C# 并发的新手,正在尝试使用两个按钮的基本应用程序,第一个按钮单击应该触发一个通过 for 循环的方法,下一个按钮单击甚至应该取消 Task t; CancellationTokenSourc
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度理解。包括尝试过的解决方案、为什么它们不起作用,以及预
给定以下代码: string injectedString = "Read string out of HttpContext"; Task.Factory.StartNew(() => {
据我所知,我有误导性信息。我需要在后台运行一个单独的线程。 目前我是这样做的: var task = Task.Factory.StartNew (CheckFiles
一个简单的问题。这是 WinForms 应用程序的一部分: void Form1_Load(object sender, EventArgs e) { var task2 = Task.Fac
我是一名优秀的程序员,十分优秀!