簡體   English   中英

誰能告訴哪個代碼塊進行並行操作以及為什么?

[英]Can anyone tell which code block does parallel operation and why?

代碼塊 1:-

var services1 = new service1();
var services2 = new service2();
var result1 = await service1.GetData();
var result2 = await service2.GetData();

代碼塊 2:-

var services1 = new service1();
var services2 = new service2();
var task1 = await service1.GetData();
var task2 = await service2.GetData();
Task.WhenAll(task1,task2);

今天我的測驗中有這些問題..!

作為選項,從其中選擇一個 CB1 或 CB2。

在此處輸入圖像描述

只要await service1.GetData()不引發異常,您的第一個示例就可以了。 如果是這樣,那么await service2.GetData()的結果或拋出的任何異常都將丟失。

但是,它將序列化操作,因為在service2.GetData() service1.GetData()

除非您打算這樣做,否則您的第二個示例將無法編譯:

var service1 = new service1();
var service2 = new service2();
var task1 = service1.GetData();
var task2 = service2.GetData();
await Task.WhenAll(task1, task2);

等待Task.WhenAll而不是service1.GetData()service2.GetData()的地方。

然后你可以安全地訪問這樣的結果:

var result1 = task1.Result;
var result2 = task2.Result;

這里的區別在於只有一個地方可以拋出異常: Task.WhenAll ,它將聚合來自所有提供的任務的異常。

它還允許在執行service2.GetData() () 完成的任何異步工作時調用service1.GetData()


還有第三個選項,假設service1.GetData()service2.GetData()具有相同的返回類型:

var service1 = new service1();
var service2 = new service2();
var results = await Task.WhenAll(services1.GetData(), services2.GetData());

這樣,每個Task的結果將被添加到一個數組中(這里results )。

然后,您可以提取各個值:

var result1 = results[0];
var result2 = results[1];

通常我不會回答作業問題,因為你應該在 class 中學習過它。 但我覺得有必要回答這個問題,因為這是一個糟糕的問題,而且我擔心你會被幫助誤解異步編程。

並行。=異步。

“並行”是指同時執行兩段或多段代碼。 這意味着有不止一個線程。 它是關於代碼如何運行的。

“異步”意味着當一個代碼塊在等待一些外部操作時,線程被釋放來做一些其他的工作,而不是鎖定線程。 這是關於代碼如何等待的。

假設GetData()發出網絡請求以獲取數據。 這就是第二個示例中發生的情況:

  1. service1.GetData()一直運行到發送網絡請求並返回一個Task
  2. service2.GetData()一直運行到發送網絡請求並返回一個Task

到目前為止,兩個網絡請求都已發送,我們正在等待響應。 一切都發生在同一個線程上,而不是並行發生。 但是我們仍然需要在收到每個響應后運行每個(在GetData()await之后的所有內容)的延續。 它們的運行方式取決於應用程序是否具有同步上下文。

  • 如果存在同步上下文(例如 ASP.NET 或 UI 應用程序),則不會並行運行。 GetData()的每次調用的延續將在同一線程上一個接一個地運行。
  • 如果沒有同步上下文(例如,在GetData()中使用了 ASP.NET Core 或控制台應用程序或ConfigureAwait(false) ),那么每個延續將在響應返回后立即在 ThreadPool 線程上運行,這可能會發生在平行下。

如果你的老師要你打B,那么就寫出你能得到分數的答案。 但它實際上可能是錯誤的,除非您已獲得有關應用程序類型的更多詳細信息以及它是否具有同步上下文。

此外,在Task.WhenAll()之前應該有一個await

Microsoft 有一系列關於使用 async 和 await 進行異步編程的優秀文章值得一讀。 您可以在第一篇文章左側的目錄中找到該系列中的其他文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM