[英]What causes a Task to complete?
我試圖找出如何使用WhenAll
讓兩種方法同時運行,而一旦他們都完成,收集結果,而不使用阻斷.Result
我有這個小的控制台應用程序測試:
using System.Diagnostics;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
public static void Main(string[] args)
{
var run = TaskRunner();
Debug.WriteLine(run);
if (run.IsCompleted)
{
Debug.WriteLine("this worked!");
} else
{
Debug.WriteLine("this failed!");
}
}
public static async Task<string> TaskRunner()
{
var taskOne = OneAsync();
var taskTwo = TwoAsync();
var tasks = await Task.WhenAll(taskOne, taskTwo);
var retval = tasks[0] + tasks[1];
return retval;
}
public static Task<string> OneAsync()
{
return Task.Run(() =>
{
return "test1";
});
}
public static Task<string> TwoAsync()
{
return Task.Run(() =>
{
return "test2";
});
}
}
}
當前打印this worked!
作品this worked!
到我的輸出窗口...但是,如果我注釋掉Debug.WriteLine(run);
它打印this failed!
...為什么僅通過登錄到輸出窗口即可完成任務?
我試圖理解一段復雜的代碼中的一個巨大問題,而這個小測試是我的MCVE,希望可以對幕后發生的事情有所了解。
這只是偶然的機會。 開始任務的方式是使用Task.Run
。 這實質上創建了一個新線程,在該線程上執行(同步)動作。 它返回一個任務以完成該線程。
因此, OneAsync
和TwoAsync
將各自產生一個新線程,然后立即返回一個字符串。 這將很快發生,但是創建那些線程仍然有一些開銷,這意味着它不會是瞬時的 。
然后, TaskRunner
調用這兩個方法(生成線程),然后異步等待兩個線程完成。 由於線程不是立即完成的,因此TaskRunner
方法也不會立即完成。
現在,您主要是在啟動異步TaskRunner
,我們認為這將花費“很短的時間” 。 你不等待任務,所以執行立即繼續。 執行Debug.WriteLine
來打印某些內容(可能要打印的是相關任務,這實際上並不重要), 然后您正在檢查任務的狀態。
由於打印內容相對較慢(與其他操作相比),這可能是任務最終完成的原因。 而且,當您刪除打印件時, if
太快了,無法完成任務。
正如您可能注意到的那樣,與異步任務一起工作似乎不是一個好主意。 因此,當您依賴任務的結果時,應該始終等待它。
// note the *async* here; async main methods are supported with C# 7.1
public static async void Main(string[] args)
{
var run = TaskRunner();
// await the task
await run;
if (run.IsCompleted)
{
Debug.WriteLine("this worked!");
}
else
{
Debug.WriteLine("this failed!");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.