2017-10-11 2 views
0

Ich versuche, die AsyncEnumerator von https://www.nuget.org/packages/AsyncEnumerator/AsyncEnumerator warten nicht auf Aufgabe

Also verwende ich die Methode genau jedoch die gleiche wie ihr Beispiel schrieb, ist meine Aufgabe nicht warten, wo sein sollte und verlässt nur die Programme .

Ich rief die asynchrone fillData_async, und im Inneren haben sie eine Parallele, die meine langen Aufgaben ausführt und warten soll.

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(); 
    } 

meine Asynchron-Methoden:

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

'String log + = fillData_Async (Concurrent_PhoneNoList);' Ich bin überrascht, dass diese kompiliert auch ohne 'await' oder rufen Sie an die' .Result' Eigenschaft. –

+0

Es scheint, dass 'Form1_Load' nicht auf das Beenden der asynchronen Methode wartet und dann Application.Exit()' aufruft, während die Methode noch ausgeführt wird. –

+0

ja es kompiliert, soll es nicht so sein? –

Antwort

0

Sie warten nicht für FillData_Async beenden zu. hinzufügen .Result bis zum Ende, oder await es

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

oder

string log += await fillData_Async(Concurrent_PhoneNoList); 

Wenn Sie den await, Ansatz wählen, werden Sie die Rufmethode Async machen.

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

das Hinzufügen .Result funktioniert, danke! –

+0

Die Verwendung von AsyncMethod(). Result ist ein falscher Ansatz für "wirklich" asynchrone Methoden wegen möglicher Deadlocks. Aber es wird im OP-Fall nur funktionieren, weil sein Code eindeutig synchron ist, es gibt keine asynchronen Methoden. 'await callWebServiceTask (item.phoneNo);' wird synchron ausgeführt, da die bereits abgeschlossene Aufgabe zurückgegeben wird. – Fabio

+0

Hallo, nur um zu aktualisieren, nachdem ich einige Sachen geändert habe, resultierte das .Result in einer toten Sperre, die Form1_Load async Methode arbeitete –

Verwandte Themen