2017-10-11 155 views
0

我試圖使用AsyncEnumerator從https://www.nuget.org/packages/AsyncEnumerator/AsyncEnumerator不是等待任務

所以我寫的方法完全一樣,他們的榜樣然而,我的任務是不是在哪裏是應該等待,只是退出程序。

我叫async fillData_async,裏面有一個parallelloop,它運行我的長期任務,應該等待。

private void Form1_Load(object sender, EventArgs e) 
    { 

     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     ConcurrentBag<phoneData> Concurrent_PhoneNoList = new ConcurrentBag<phoneData>(); 

     using (SqlCommand cmd = new SqlCommand("Select * FROM numbers", conn)) 
     { 
      conn.Open(); 
      SqlDataReader reader = cmd.ExecuteReader(); 

      while (reader.Read()) 
      { 
       phoneData temp = new phoneData(); 

       int phoneno = 0; 

       if (int.TryParse(reader["number"].ToString(), out phoneno) == true) 
       { 
        temp.phoneID = (int.Parse(reader["id"].ToString())); 
        temp.phoneNo = phoneno; 
       } 

       Concurrent_PhoneNoList.Add(temp); 
      } 

      conn.Close(); 
     } 

     string log += fillData_Async(Concurrent_PhoneNoList); // calls async here 

     stopwatch.Stop(); // instantly continues without waiting 
     TimeSpan ts = stopwatch.Elapsed; 
     string.Format("{0}:{1}", Math.Floor(ts.TotalMinutes), ts.ToString("ss\\.ff")); 

     log += "TotalTime: " + ts; 

     Application.Exit(); 
    } 

我的異步方法:

private async Task<string> fillData_Async(ConcurrentBag<phoneData> phoneNolist) 
    { 
     string log = "Total Lines Retrieved From Database : " + phoneNolist.Count + "<br/>"; 

     int failures = 0; 
     await phoneNolist.ParallelForEachAsync(async item => 
     { 
      string returned_Data = await callWebServiceTask(item.phoneNo); 

      if (returned_Data != "Failed") 
      { 
       item.Data = returned_Data; 
      } 
      else 
      { 
       //failedList1.Add(temp); 
       failures++; 
      } 

     }, maxDegreeOfParalellism: 20); 

     log += "Number of failures : " + failures; 

     return log; 
    } 

    private Task<string> callWebServiceTask(int phoneNo) 
    { 
     string datareturned = myverylongtask(phoneNo); // public static string 
     return Task.FromResult(datareturned); 
    } 
+0

'字符串日誌+ = fillData_Async(Concurrent_PhoneNoList);'我很驚訝,這甚至編譯沒有'await'或調用'.Result'屬性。 –

+0

看來發生的情況是Form1_Load沒有等待異步方法完成,然後在方法仍在運行時調用Application.Exit()。 –

+0

是的它編譯,它不應該是這樣嗎? –

回答

0

你不等待FillData_Async完成。添加.Result到最後,還是await

// note: if you wait on a task like this from inside an async method, 
// deadlocks might happen. 
string log += fillData_Async(Concurrent_PhoneNoList).Result; 

string log += await fillData_Async(Concurrent_PhoneNoList); 

如果選擇await,方法,你將不得不作出調用方法Async

// async void should *only* be used for event handlers 
private async void Form1_Load(object sender, EventArgs e) 
{ 
    ... 
+0

加入.Result的作品,謝謝! –

+0

使用'AsyncMethod()。由於可能的死鎖,「結果」對於「真正」異步方法是錯誤的方法。但它將在OP的情況下工作,只是因爲他的代碼顯然是同步的,沒有異步方法。 '等待callServiceServiceTask(item.phoneNo);'將同步執行,因爲它返回已經完成的任務。 – Fabio

+0

嗨,只是爲了更新,我改變了一些東西后,.Result導致死鎖,Form1_Load異步方法工作 –