2017-04-14 137 views
0

該程序不會按正確的順序打印輸出。異步和等待C#和問題

public static void Main(string[] args) 
    { 
     new Program().Start(); 
    } 

    public async void Start() 
    { 
     int num1 = await GetNumber(); 
     int num2 = await GetNumber(); 
     int num3 = await GetNumber(); 
     Console.WriteLine("Wait..."); 
     Console.ReadKey(); 
    } 

    public static async Task<int> GetNumber() 
    { 
     System.Threading.Thread.Sleep(4000); 
     Console.WriteLine("Hello"); 
     return 0; 
    } 

它輸出:

--------wait 4Seconds 
--------print Hello 
--------wait 4Seconds 
--------print Hello 
--------wait 4Seconds 
--------print Hello 
--------print wait.... 

它應該輸出

--------print wait.... 
--------wait 4Seconds 
--------print Hello 
--------print Hello 
--------print Hello 
+3

你在GetNumber之前使用await關鍵字,我認爲它會等待操作,並且在前一個沒有完成的時候沒有移動光標到下一個命令。 –

回答

1

await的意思是「打破這裏一半的方法,回來後,當這個調用完成」。這就是你如何將Task<T>「轉換」爲T:通過等待(等待)任務。否則,你會被卡住Task<T>

好像你正在尋找的卻是等待任務,使它們異步運行,但如果你這樣做,那麼你將無法得到int結果。

(由於對方的回答中提到,您還需要await東西GetNumber或不會實際上是異步的。)

喜歡的東西:

public static void Main(string[] args) { 
    new Program().Start(); 
} 

public void Start() { 
    GetNumber(); 
    GetNumber(); 
    GetNumber(); 
    Console.WriteLine("Wait..."); 
    Console.ReadKey(); 
} 

public static async Task<int> GetNumber() { 
    await Task.Delay(TimeSpan.FromSeconds(1)); 
    Console.WriteLine("Hello"); 
    return 0; 
} 

應該給輸出你期望:

稍候...
你好
你好
你好

8

使用

Await Task.Delay(Timespan.FromMilliSeconds (4000)) 

代替了Thread.Sleep。

完全成功的例子。

using System; 
using System.Threading.Tasks; 

namespace Brad 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var task = new Program().Start(); 
      Console.WriteLine("Wait..."); 
      // You have to put a synchronous Wait() here because 
      // Main cannot be declared as async 
      task.Wait(); 
     } 

     public async Task Start() 
     { 
      int num1 = await GetNumber(); 
      int num2 = await GetNumber(); 
      int num3 = await GetNumber(); 
      Console.WriteLine("Finished"); 
     } 

     public static async Task<int> GetNumber() 
     { 
      await Task.Delay(TimeSpan.FromMilliseconds(400)); 
      Console.WriteLine("Hello"); 
      return 0; 
     } 
    } 
} 

你可以看到在這裏運行

https://dotnetfiddle.net/KHJaDZ

或者你想在並行,而不是一個接一個運行的任務。你可以嘗試

using System; 
using System.Threading.Tasks; 

namespace Brad 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var task = new Program().Start(); 
      Console.WriteLine("Wait..."); 
      // You have to put a synchronous Wait() here because 
      // Main cannot be declared as async 
      task.Wait(); 
     } 

     public async Task Start() 
     { 
      var task1 = GetNumber(); 
      var task2 = GetNumber(); 
      var task3 = GetNumber(); 
      // This runs the tasks in parallel 
      await Task.WhenAll(task1, task2, task3); 
      Console.WriteLine("Finished"); 
     } 

     public static async Task<int> GetNumber() 
     { 
      await Task.Delay(TimeSpan.FromMilliseconds(400)); 
      Console.WriteLine("Hello"); 
      return 0; 
     } 
    } 
} 

這是在這裏運行。

https://dotnetfiddle.net/kVk77Z

+0

當我使用它時,我的應用程序關閉了 public static void Main(string [] args) { {0}新的Program()。開始(); () } public async void開始() { int num1 = await GetNumber(); int num2 = await GetNumber(); int num3 = await GetNumber(); Console.WriteLine(「Wait ...」); Console.ReadKey(); } public static async任務 GetNumber() await Task.Delay(TimeSpan.FromMilliseconds(1000)); Console.WriteLine(「Hello」); return 0; } –

+0

我寫過你現在兩個版本的同一個程序。一個串行運行任務,另一個並行運行任務。他們都經過測試,應該會幫助你理解。 :) – bradgonesurfing