2016-01-20 58 views
2

在下面的代碼:C#異步功能任務<int>

async static Task<int> test(){ 
    Console.WriteLine("{0}: Start 3", DateTime.Now); 
    await Task.Delay(3000); 
    return 3; 
} 

List<Task<int>> tasks2 = new List<Task<int>> { 
    test(), 
    new Task<int>(delegate { Console.WriteLine("{0}: Start 3", DateTime.Now); Task.Delay(3000).Wait(); return 3; }), 
    new Task<int>(delegate { Console.WriteLine("{0}: Start 1", DateTime.Now); Task.Delay(1000).Wait(); return 1; }), 
}; 


foreach (var task in tasks2) 
    task.Start(); // this cause exception at runtime 

爲什麼我不能用test方法Task<int>?如果函數返回Task<int> ...

回答

0

正如其他人所說,因爲它已經開始,您不能撥打Start。如果這是你想要的,你仍然可以通過檢查狀態來實現你的目標。請參閱下面的更新的代碼:

async static Task<int> test(){ 
    Console.WriteLine("{0}: Start 3", DateTime.Now); 
    await Task.Delay(3000); 
    return 3; 
} 


     List<Task<int>> tasks2 = new List<Task<int>> { 
      new Task<int>(delegate{ return test().Result;}), 
      new Task<int>(delegate { Console.WriteLine("{0}: Start 3", DateTime.Now); Task.Delay(3000).Wait(); return 3; }), 
      new Task<int>(delegate { Console.WriteLine("{0}: Start 1", DateTime.Now); Task.Delay(1000).Wait(); return 1; }), 
      }; 

foreach (var task in tasks2) 
{ 
     task.Start(); 
} 
+0

我同意,它已經開始。有沒有辦法,將任務的測試功能通過列表>? – tower120

+0

我的意思是通過它作爲未開始的任務。就好像它是新的任務(委託{... – tower120

+0

我已經更新了List初始化部分,現在可以在需要時調用'Start'。 – Martin

3

當您調用test()時,由test()返回的任務已啓動。所以你不能再啓動它。

實際上,test()返回的任務是承諾式任務,首先不會在線程池線程上運行。

您應該幾乎總是創建已經開始的任務(一旦它們被創建)。

也就是說,您不應該使用Task的構造函數,然後調用Start方法。

相反,如果要在線程池線程上運行該任務,請使用Task.Run

+0

「你應該幾乎總是創建已經開始的任務(一旦它們被創建)」。 - 爲什麼?如果我想要後者運行呢? – tower120

+0

「test()返回的任務是一個promise類型的任務」 - 這是什麼? – tower120

+3

因爲'Task.Run'是一個更好的選擇。看看[這篇文章](http://blog.stephencleary.com/2015/02/a-tour-of-task-part-8-starting.html)。如果你想創建一些東西然後啓動它,使用'Action ',然後通過'Task.Run'啓動它。 –

0

像其他人一樣指出,任務已經開動的時候,你叫test()所以你不能在它重新開始。給下面的代碼一個鏡頭,看看發生了什麼。

正如您所看到的,控制檯輸出來自每項任務。通過調用該方法啓動test()返回的任務。因此,此代碼僅明確地啓動Created狀態中的其他任務。最後,我們通過調用WhenAll()來完成所有任務,然後返回一個我們等待的任務。在「全部完成」之前,您會注意到3秒(所有任務)的最長延遲時間。被打印。

public static class AsyncTest 
{ 
    static async Task<int> test() 
    { 
     Console.WriteLine("{0}: Start 3", DateTime.Now); 
     await Task.Delay(3000); 
     return 3; 
    } 

    public static void Main() 
    { 

     var tasks2 = new List<Task<int>> 
     { 
      test(), 
      new Task<int>(delegate { Console.WriteLine("{0}: Start 3", DateTime.Now); Task.Delay(3000).Wait(); return 3; }), 
      new Task<int>(delegate { Console.WriteLine("{0}: Start 1", DateTime.Now); Task.Delay(1000).Wait(); return 1; }) 
     }; 

     foreach (var task in tasks2) 
     { 
      if (task.Status == TaskStatus.Created) 
       task.Start(); 
     } 

     Task.WhenAll(tasks2).Wait(); 

     Console.WriteLine("All done!"); 
    } 
}