C# 在异步方法中如何以及在何处应用wait

C# 在异步方法中如何以及在何处应用wait,c#,C#,我不熟悉异步,在c#中等待。我正在尝试读取大约300个文本文件,其中我使用的是调用函数“ReadFiles”的List。我使这个函数异步,但我不知道现在如何修改代码以使用wait。我应该在哪里使用wait关键字,这样它就可以运行我的程序而不会抛出错误。任何帮助都将不胜感激。下面是我的代码: List<Task> tasks = new List<Task>(); foreach (var file in folderFiles) { var task = Task

我不熟悉异步,在c#中等待。我正在尝试读取大约300个文本文件,其中我使用的是调用函数“ReadFiles”的List。我使这个函数异步,但我不知道现在如何修改代码以使用wait。我应该在哪里使用wait关键字,这样它就可以运行我的程序而不会抛出错误。任何帮助都将不胜感激。下面是我的代码:

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;
}
List tasks=newlist();
foreach(folderFiles中的var文件)
{
var task=task.Factory.StartNew(()=>
{
ReadFile(file.FullName、folderPath、folder.Name、week);
});
任务。添加(任务);
}
Task.WaitAll(tasks.ToArray());
DateTime stoptime=DateTime.Now;
TimeSpan totaltime=停止时间。减去(开始时间);
label6.Text=Convert.ToString(总时间);
textBox1.Text=folderPath;
DialogResult result2=MessageBox.Show(“成功读取文件”。,“重要消息”,MessageBoxButtons.OK,MessageBoxIcon.Information);
公共异步void ReadFile(字符串文件、字符串folderPath、字符串folderName、字符串周)
{
int LineCount=0;
string fileName=Path.GetFileNameWithoutExtension(文件);
使用(FileStream fs=File.Open(File,FileMode.Open))
使用(BufferedStream bs=新的BufferedStream(fs))
使用(StreamReader sr=新StreamReader(bs))
{
对于(int i=0;i<2;i++)
{
sr.ReadLine();
}
线状奥林;
而((oline=sr.ReadLine())!=null)
{
LineCount=++LineCount;
字符串[]eachLine=oline.Split(“;”);
字符串日期=eachLine[30]。子字符串(1)。子字符串(0,10);
日期时间dt;
bool valid=DateTime.TryParseExact(日期,“dd/MM/yyyy”,CultureInfo.InvariantCulture,datetimestyle.None,out dt);
如果(!有效)
{
Filecount=++Filecount;
StreamWriter sw=新的StreamWriter(folderPath+“/”+”文件\u格式错误\u日期\u格式\u“+folderName+”.txt”,为真);
sw.WriteLine(文件名+++--“++”行号:“++”+LineCount);
sw.Close();
}
其他的
{
DateTime Date=DateTime.ParseExact(日期,“d/M/yyyy”,CultureInfo.InvariantCulture);
int calculatedWeek=新的GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(日期,CalendarWeekRule.FirstFourDayWeek,DayOfWeek.Saturday);
如果(calculatedWeek==转换为32(周))
{
}
其他的
{
Filecount=++Filecount;
StreamWriter sw=新的StreamWriter(folderPath+“/”+”文件,其日期与相应的周不匹配,“+folderName+”.txt”,true);
sw.WriteLine(文件名+++--“++”行号:“++”+LineCount);
sw.Close();
}
}       
}
}
//返回true;
}

您需要更改

public async void ReadFile(string file, string folderPath, string folderName, string week)<br/>
public async void ReadFile(字符串文件、字符串folderPath、字符串folderName、字符串周)
并让它返回一个任务,最好是在方法末尾返回您想要的值。
因为async void一起使用意味着开火和遗忘。这意味着它将开始执行,而不是等待它完成,而是在后台继续执行的同时执行其余语句。因此,您将成功地接收到
读取文件。
消息,甚至在您完成读取文件之前。

您需要进行一些更改

首先将void更改为Task

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

我知道这不是您直接要求的,但您不应该将async/Wait与多线程混淆。因此,如果您所追求的是多个线程“同时”处理不同的文件,则不应使用async/await


如果这不是您想要的,但是您实际想要的是异步/等待,那么您需要使用异步方法从中实际获得任何东西。因此,在StreamReader/StreamWriter上调用WriteLine/ReadLine时,实际上应该使用WriteLineAsync方法和ReadLineAsync方法。否则就没有收获。

谢谢。早些时候,我的“ReadFile”函数是bool,但有人建议我使用async和wait,因为我的程序在执行300个文本文件时花费了太多时间。您能告诉我如何在现有代码中使用async和Wait吗?不客气。但在我看来,如果您只读取异步任务ReadFile中的文件,不计算任何内容并返回文件状态,然后收集所有300个状态并执行其余操作,那么它会更好,性能也会更好。这样,你就不需要锁或任何其他同步了。我用同样的方法做的……结果非常棒。现在,在大约17GB的数据上进行迭代大约需要5.30分钟。谢谢:)
lock(new object())
{
     Filecount++;
}