C# 在异步方法中如何以及在何处应用wait
我不熟悉异步,在c#中等待。我正在尝试读取大约300个文本文件,其中我使用的是调用函数“ReadFiles”的List。我使这个函数异步,但我不知道现在如何修改代码以使用wait。我应该在哪里使用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
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++;
}