这是AsyncMethods
类的样子:
public class AsyncMethods
{
public static async Task<double> GetdoubleAsync()
{
Console.WriteLine("Thread.CurrentThread.ManagedThreadId: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
return 80d;
}
public static async Task<string> GetStringAsync()
{
Console.WriteLine("Thread.CurrentThread.ManagedThreadId: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
return "async";
}
public static async Task<DateTime> GetDateTimeAsync()
{
Console.WriteLine("Thread.CurrentThread.ManagedThreadId: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
return DateTime.Now;
}
}
这是我的主要方法:
static void Main(string[] args)
{
while (Console.ReadLine() != "exit")
{
Console.WriteLine("Thread.CurrentThread.ManagedThreadId: " + Thread.CurrentThread.ManagedThreadId);
DateTime dt = DateTime.Now;
var res = GetStuffAsync().Result;
var ts = DateTime.Now - dt;
Console.WriteLine(res);
Console.WriteLine("Seconds taken: " + ts.Seconds + " milliseconds taken: " + ts.Milliseconds);
}
Console.ReadLine();
return;
}
static async Task<object> GetStuffAsync()
{
var doubleTask = AsyncMethods.GetdoubleAsync();
var StringTask = AsyncMethods.GetStringAsync();
var DateTimeTask = AsyncMethods.GetDateTimeAsync();
return new
{
_double = await doubleTask,
_String = await StringTask,
_DateTime = await DateTimeTask,
};
}
从每种方法中可以看出,我增加了1秒的延迟。这是输出:
Thread.CurrentThread.ManagedThreadId: 10
Thread.CurrentThread.ManagedThreadId: 10
Thread.CurrentThread.ManagedThreadId: 10
Thread.CurrentThread.ManagedThreadId: 10
{ _double = 80, _String = async, _DateTime = 2/15/2017 4:32:00 AM }
Seconds taken: 1 milliseconds taken: 40
Thread.CurrentThread.ManagedThreadId: 10
Thread.CurrentThread.ManagedThreadId: 10
Thread.CurrentThread.ManagedThreadId: 10
Thread.CurrentThread.ManagedThreadId: 10
{ _double = 80, _String = async, _DateTime = 2/15/2017 4:32:03 AM }
Seconds taken: 1 milliseconds taken: 16
现在我有两个问题:
答案 0 :(得分:12)
首先:如果您有两个问题请提出两个问题。不要在一个问题中提出两个问题。
为什么一切都发生在一个线程上?
这是一个错误的问题。正确的问题是:为什么你认为任何事情都应该发生在第二个线程上?
在这里,我给你一个任务:等五分钟,然后查看你的电子邮件。在你等待的时候,做一个三明治。 您是否需要雇人才能做等待或制作三明治?显然不是。线程是工人。如果工作可由一名工人完成,则无需雇用工人。
如果您不需要,await
的重点是避免进入额外的主题。在这种情况下,你不需要。
为什么延迟时间仅为1秒,等待3秒钟?
比较这两个工作流程。
如果您执行该工作流程,您将等待总共十五分钟。
您编写的工作流程是:
您只需等待五分钟即可完成该工作流程;所有延迟都是在同一时间发生的。
你现在看到你的程序编写错误吗?
要理解的关键洞察力是等待是程序中的一个点,其中await的延续被延迟到等待任务完成之后。
如果您没有等待,该程序将自行继续,无需等待。这就是await
的含义。
答案 1 :(得分:1)
他们在同一个线程上启动。当您按顺序调用三个异步方法时,它们都会同步执行,直到第一个await
调用。 (在await
之后,它们成为状态机,只要它们被安排就会从它们停止的地方开始。如果你在<{em> await Task.Delay
电话之后检查了线程ID ,你可能会发现延续在不同的线程上运行 - 至少在控制台应用程序中运行。)
至于为什么它只延迟1秒......这就是你告诉它要做的事情。您有三个异步任务,所有任务同时运行,每个延迟一秒钟。你不是说&#34; [a]等到第一个任务完成后再开始第二个任务&#34; - 实际上你正在小心翼翼地做相反的事情,从三个开始然后等待所有三个 - 所以它们并行运行。
答案 2 :(得分:0)
您的Console.WriteLine()调用GetdoubleAsync(),GetStringAsync()和GetDateTimeAsync()在调用线程中发生,因为它们发生在第一次继续之前。
你的await Task.Delay()调用使线程返回到调用代码。
当Task.Delay()返回的任务完成后,这些任务的继续返回其值并将其任务设置为已完成。
这使得GetStuffAsync()中的3个等待(按顺序,同步顺序)返回。在标记为完成之前,每个人都必须等待1秒,但他们同时正在屈服并发生。
我认为您正在寻找System.Threading.Tasks.Parallel来同时执行操作。 Async ... await对于产生线程非常有用。
答案 3 :(得分:0)
您同时启动所有任务,这样他们就可以并行运行,而不是按顺序运行。这就是为什么一切都在1000毫秒后完成的原因。
此外,async
不会创建新线程,它会异步使用当前线程。您可以在异步javascript(这是一个单线程环境)或Unity3D中的协程中看到这种行为。它们都允许没有线程的异步行为。
因此,您的每个任务都在同一个线程上运行,并在1秒内完成。