簡體   English   中英

Task.WaitAll - 不等待?

[英]Task.WaitAll - Not Waiting?

我試圖在任務並行庫中找到Task.WaitAll(..)。

我正在使用以下代碼運行測試以嘗試模擬兩個任務,一個將比指定的等待時間(10秒)運行更長時間(10秒),一個運行時間少於指定的時間(3秒)等待的時間。指定的時間是5秒。我使用的代碼如下:

Task<int>[] tasks = new Task<int>[]
{
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(10000);
            return 1;
        }),
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(3000);
            return 2;
        })
};

TimeSpan timeSpan = new TimeSpan(0, 0, 5);
Task.WaitAll(tasks,timeSpan);

int[] results = new int[tasks.Length];
for(int i = 0; i < tasks.Length;i++)
{
    Console.WriteLine(tasks[i].Result);
}

至於timeSpan,我也嘗試直接傳入5000而不是timeSpan變量,但它不起作用。 我得到以下輸出:

1
2

我希望只得到以下輸出,因為另一個線程的執行時間超過了預期的等待時間。

1

我誤解了這個,還是做錯了?

雖然Task.Delay是您通常想要使用的(因此您不會在睡眠期間浪費線程),但您的問題實際上與此無關。

這里發生的是當你打印出結果時,你正在訪問每個任務的Result屬性。 這會阻止任務完成,所以你在WaitAll中等待5秒,然后在打印出10秒任務的結果時再等5秒。

根據您聲明的意圖,您需要在訪問結果之前檢查任務狀態,因為您的意圖不是阻止它,而只是在碰巧已經完成時將其打印出來:

int[] results = new int[tasks.Length];
for (int i = 0; i < tasks.Length; i++)
{
    if (tasks[i].IsCompleted)
    {
        Console.WriteLine(tasks[i].Result);
    }
}

順便說一句,您可以通過添加一些簡單的時間檢查(例如,使用秒表,這樣)來顯示“結果上的阻止”是原始代碼中發生的情況。

Task<int>[] tasks = new Task<int>[]
{
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(10000);
            return 1;
        }),
    Task.Factory.StartNew<int>(()=>
        {
            Thread.Sleep(3000);
            return 2;
        })
};

TimeSpan timeSpan = new TimeSpan(0, 0, 5);
var stopwatch = Stopwatch.StartNew();
Task.WaitAll(tasks, timeSpan);
Console.WriteLine("WaitAll took {0} seconds", stopwatch.Elapsed.TotalSeconds);

int[] results = new int[tasks.Length];
for (int i = 0; i < tasks.Length; i++)
{
    stopwatch = Stopwatch.StartNew();
    Console.WriteLine(tasks[i].Result);
    Console.WriteLine("Printing result took {0} seconds", stopwatch.Elapsed.TotalSeconds);
}

這會產生以下控制台輸出:

WaitAll took 4.9996961 seconds
1
Printing result took 5.0050012 seconds
2
Printing result took 0.0004338 seconds

不要在任務中使用Thread.Sleep。 Task調度程序不保證每個任務一個線程,而休眠可能會影響其他任務(請參閱任務忽略Thread.Sleep )。 請改用Task.Delay()

嘗試將你的時間跨度轉換為

TimeSpan span = new TimeSpan(0, 0, 0, 10, 0);
//TimeSpan(Days, hours, minutes, seconds, milliseconds);

暫無
暫無

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

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