2016-02-04 51 views
1

我是新來的異步和等待在C#中。我正在嘗試讀取我正在使用調用函數「ReadFiles」的List的300個文本文件。我做了這個函數異步,但我不知道如何修改我的代碼現在使用await。我應該在哪裏使用await關鍵字,以便它可以運行我的程序而不會引發錯誤。任何幫助,將不勝感激。下面是我的代碼:如何以及在哪裏我可以申請等待我的異步方法

List<Task> tasks = new List<Task>(); 
foreach (var file in folderFiles) 
{ 
    var task = Task.Factory.StartNew(() => 
    { 
     ReadFile(file.FullName, folderPath, folder.Name, week); 
    }); 
    tasks.Add(task); 
} 

Task.WaitAll(tasks.ToArray()); 
DateTime stoptime = DateTime.Now; 
TimeSpan totaltime = stoptime.Subtract(starttime); 
label6.Text = Convert.ToString(totaltime); 
textBox1.Text = folderPath; 
DialogResult result2 = MessageBox.Show("Read the files successfully.", "Important message", MessageBoxButtons.OK, MessageBoxIcon.Information); 

public async void ReadFile(string file, string folderPath, string folderName, string week) 
{ 
    int LineCount = 0; 
    string fileName = Path.GetFileNameWithoutExtension(file); 

    using (FileStream fs = File.Open(file, FileMode.Open)) 
    using (BufferedStream bs = new BufferedStream(fs)) 
    using (StreamReader sr = new StreamReader(bs)) 
    { 
     for (int i = 0; i < 2; i++) 
     { 
      sr.ReadLine(); 
     } 

     string oline; 
     while ((oline = sr.ReadLine()) != null) 
     { 
      LineCount = ++LineCount; 
      string[] eachLine = oline.Split(';'); 

      string date = eachLine[30].Substring(1).Substring(0, 10); 

      DateTime dt; 

      bool valid = DateTime.TryParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); 

      if (!valid) 
      { 
       Filecount = ++Filecount; 
       StreamWriter sw = new StreamWriter(folderPath + "/" + "Files_with_wrong_date_format_" + folderName + ".txt", true); 
       sw.WriteLine(fileName + " " + "--" + " " + "Line number :" + " " + LineCount); 
       sw.Close(); 
      } 
      else 
      { 
       DateTime Date = DateTime.ParseExact(date, "d/M/yyyy", CultureInfo.InvariantCulture); 

       int calculatedWeek = new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Saturday); 

       if (calculatedWeek == Convert.ToInt32(week)) 
       { 

       } 
       else 
       { 
        Filecount = ++Filecount; 
        StreamWriter sw = new StreamWriter(folderPath + "/" + "Files_with_dates_mismatching_the_respective_week_" + folderName + ".txt", true); 
        sw.WriteLine(fileName + " " + "--" + " " + "Line number :" + " " + LineCount); 
        sw.Close(); 
       } 
      }  
     } 
    } 
    //return true; 
} 

回答

1

您需要進行幾項更改。

首先改變空隙任務

public async Task ReadFile(string file, string folderPath, string folderName, string week) 

第二個變化sw.WriteLine等待sw.WriteLineAsync

await sw.WriteLineAsync(fileName + " " + "--" + " " + "Line number :" + " " + LineCount); 

最後,調用方法爲波紋管。

List<Task> tasks = new List<Task>(); 
     foreach (var file in folderFiles) 
     { 
      var task = ReadFile(file.FullName, folderPath, folder.Name, week); 
      tasks.Add(task); 
     } 
     Task.WhenAll(tasks); 

此外,您還需要將Filecount變量同步:

lock(new object()) 
{ 
    Filecount++; 
} 
+0

它的工作原理。謝謝.. :) – N2J

+0

不客氣。但在我看來,如果您只是讀取async Task ReadFile內的文件,並且不計算任何內容並返回文件狀態,那麼收集所有300個狀態並執行其他操作會更好,並且表現良好。這樣,您不需要鎖定或任何其他同步。 –

+0

我以同樣的方式做到了......結果令人敬畏。現在需要大約5.30分鐘來處理大約17 GB的數據。謝謝 :) – N2J

0

您需要更改

public async void ReadFile(string file, string folderPath, string folderName, string week)<br/> 

,並使其返回工作最好要在方法的最後的值。因爲同時使用async void一起意味着火和忘記。這意味着它將開始執行而不是等待它完成,但在後臺繼續執行時執行其餘的語句。因此,在您完成讀取文件之前,您最終會收到Read the files successfully.消息。

+0

謝謝。早些時候,我的「ReadFile」函數是bool,但有人建議我使用異步並等待,因爲我的程序花了很多時間來執行300個文本文件。你能告訴我如何使用async並在我現有的代碼中等待來幫助我。 – N2J

0

我知道這是不是你直接問什麼,但你不應該混淆異步/等待與多線程。所以如果你之後的是多個線程在「同一時間」處理不同的文件,你不應該使用async/await。

如果這不是你所追求的,但是你真正想要的是異步/等待,你需要使用異步方法來從中獲得任何東西。因此,當您在StreamReader/StreamWriter上調用WriteLine/ReadLine時,實際上應該使用WriteLineAsync方法和ReadLine異步方法。否則沒有收穫。

相關問題