简体   繁体   中英

How and where i can apply await in my async method

I am new to async and await in c#. I am trying to read some 300 text files where I am using List which is calling a function "ReadFiles". I made this function Async but I don't know how to modify my code now to use await. where should I use the await keyword so that it can run my program without throwing an error. Any help would be appreciated. Below is my code :

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

You need to make couple of changes.

First change the void to Task

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

Second change sw.WriteLine to await sw.WriteLineAsync

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

Finally, call the method as bellow.

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

Also, you need to synchronize the Filecount variable as:

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

You will need to change

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

and make it return a Task preferably the value that you want at the end of method. Since async void used together means fire and forget. Which means it will start the execution wont wait for it to complete but execute the rest of statements while continuing execution in background. So you will end up receiving Read the files successfully. message before you even finish having read file.

I know this is not directly what you ask, but you should not confuse async/await with multi-threading. So if what you're after is multiple threads handling different files at the "same time", you should not use async/await.

If this is not what you're after, but what you actually want is async/await, you need to use async methods to actually gain anything from it. So when you call WriteLine/ReadLine on the StreamReader/StreamWriter, you should actually use the WriteLineAsync method and ReadLine async method. Otherwise there's no gain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM