[英]Async methods running on same thread with no time delay
這是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個問題:
首先,如果您有兩個問題, 請問兩個問題 。 不要在一個問題中提出兩個問題。
一切如何在單個線程上發生?
這是個錯誤的問題。 正確的問題是:您為什么認為第二個線程應該發生任何事情?
在這里,我將給您一個任務:等待五分鍾,然后檢查您的電子郵件。 在等待時,做一個三明治。 您是否需要雇用某人來做等待或做三明治 ? 顯然不是。 線程是工人。 如果工作可以由一名工人完成,則無需雇用一名工人。
await
的全部目的是避免在不需要時使用額外的線程。 在這種情況下,您不需要。
為什么等待3秒時延遲只有1秒?
比較這兩個工作流程。
如果執行該工作流程,則總共要等待15分鍾。
您編寫的工作流程為:
您只需等待五分鍾即可完成該工作流程。 所有延遲都在同一時間發生。
您是否看到現在錯誤地編寫程序的方式?
在這里要理解的關鍵見解是, 等待是程序中的一點,其中等待的持續時間被延遲到等待任務完成之后 。
如果您不等待,程序將自動繼續運行而無需等待。 那就是await
的意思。
它們都從同一線程開始 。 當您依次調用三個Async方法時,它們都將同步執行直到第一個await
調用。 (在await
,它們成為狀態機,它們在計划調度時會停下來。如果在await Task.Delay
調用之后檢查線程ID,您可能會發現延續在不同的線程上運行-至少在控制台應用程序中)。
至於為什么只延遲1秒鍾...這就是您要告訴它執行的操作。 您有三個異步任務,它們同時運行,每個任務都延遲一秒鍾。 您並不是說“等到第一個任務完成后再開始第二個任務”,實際上,您正在認真地做相反的事情,先啟動所有三個,然后等待所有三個,以便它們並行運行。
您的Console.WriteLine()調用GetdoubleAsync(),GetStringAsync()和GetDateTimeAsync()發生在調用線程中,因為它們發生在第一次繼續之前。
您的等待Task.Delay()調用使線程返回到調用代碼。
當Task.Delay()返回的任務完成時,這些Task的繼續執行返回其值並將其任務設置為已完成。
這允許您在GetStuffAsync()中等待3個(按順序,同步順序)返回。 每個人都必須等待1秒鍾才能標記為已完成,但是它們同時在屈服和發生。
我認為您正在尋找System.Threading.Tasks.Parallel同時執行操作。 異步...等待對於產生線程很有用。
您要同時啟動所有任務,因此它們將並行運行,而不是依次運行。 這就是為什么一切都在1000毫秒后完成。
此外, async
不會創建新線程,而是異步使用當前線程。 您可以在異步javascript(這是一個單線程環境)或Unity3D中的協程中看到這種行為。 它們都允許沒有線程的異步行為。
因此,您的每個任務都在同一線程上運行,並在1秒內完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.