异步方法
这是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
现在我有2个问题:
- 为什么一切都发生在单个线程?
- 为什么当我等待3秒时延迟只有1秒?
他们都在同一个线程开始。当您按顺序调用三个Async方法时,它们都会同步执行,直到第一个调用为止。 (在await
后,他们成为国家机器,拿起他们离开时,他们获得计划如果后检查线程ID 的await Task.Delay
呼叫时,您可能会发现,延续运行在不同的线程 - 至少在这里在一个控制台应用程序)
至于为什么它只是拖延1秒...这就是你要告诉它做的。你有三个异步任务,全部同时运行,每个任务延迟一秒钟。你并不是说“等到第一个任务完成之后再开始第二个任务” - 事实上你正在做相反的事情,从三个开始,然后等待所有三个 - 所以他们并行运行。
在调用线程中发生GetdoubleAsync(),GetStringAsync()和GetDateTimeAsync()中的Console.WriteLine()调用,因为它们发生在第一次继续之前。
Your await Task.Delay()调用使线程返回调用代码。
当()的返回Task.Delay任务的完成,这些任务继续返回他们的价值观,并设置其任务完成。
这允许您在GetStuffAsync()的3个等待(以顺序,同步顺序)返回。每个人都必须等待1秒,然后才标记为完成,但他们正在屈服并同时发生。
我想你正在寻找System.Threading.Tasks.Parallel来同时做事情。 Async ... await对于产生线程很有用。
第一关:如果你有两个问题请问两个问题。不要在一个问题中提出两个问题。
为什么一切都发生在单个线程?
这就是错误的问题。正确的问题是:为什么你认为在第二个线程上会发生什么?
在这里,我会给你一个任务:等5分钟,然后检查你的电子邮件。当你在等待时,做一个三明治。 你有没有雇人去做等待或做三明治?很明显不是。线程是工作者。如果工作可以由一名工作人员完成,则不需要雇用一名工人。
整点await
是避免如果您不需要额外的线程。在这种情况下,你不需要。
为什么当我等待3秒时延迟只有1秒?
比较这两个工作流程。
- 等5分钟;当你在等待,做一个三明治
- 然后检查你的电子邮件
- 然后等待五分钟;当你在等待,做一个三明治
- 然后检查你的电子邮件
- 然后等待五分钟;当你在等待,做一个三明治
- 然后检查你的电子邮件
如果执行工作流程,你会等共十五分钟。
你写的工作流程是:
- 等待五分钟
- 同时,等五分钟
- 同时,等五分钟
- ,而你在等待,做一个三明治
- 然后检查您的电子邮件
You onl您需要等待五分钟的工作流程;所有的延误都发生在同一时间。
您是否看到您现在错误地编写了程序?
这里需要了解的关键是等待是程序中的一个点,其中await的延续被延迟到等待完成的任务完成后。
如果您没有等待,程序会自动继续而不等待。这就是await
的含义。
您正在同时启动所有任务,因此它们都将并行运行,而不是按顺序运行。这就是为什么一切都在1000毫秒后完成的原因。
此外,async
不会创建新线程,它会异步使用当前线程。您可以在异步JavaScript(这是单线程环境)或Unity3D中的协程中看到这种行为。它们都允许没有线程的异步行为。
因此,您的每个任务都在同一个线程上运行,并在1秒内完成。
说真的,VS没有警告你同步调用异步代码? – stt106
如果3个任务并行运行,每个任务延迟1秒,则总延迟为1秒。你为什么期望3秒延迟? – juanreyesv
@juanreyesv - 看到它们都是一样的threadids。他们如何在单线程上并行运行? –