C# 从线程获取错误的结果
我有一个小的C# 从线程获取错误的结果,c#,wpf,multithreading,file,dispatcher,C#,Wpf,Multithreading,File,Dispatcher,我有一个小的WPF应用程序,它需要枚举指定目录中的所有文件,并检查其中是否存在某个字符串。这是搜索方法: private void btnSearch_Click_1(object sender, RoutedEventArgs e) { Thread t = new Thread(()=>search(@"c:\t", "url", true)); t.Start(); } private void search(string path, string textToSearch
WPF
应用程序,它需要枚举指定目录中的所有文件,并检查其中是否存在某个字符串。这是搜索方法:
private void btnSearch_Click_1(object sender, RoutedEventArgs e)
{
Thread t = new Thread(()=>search(@"c:\t", "url", true));
t.Start();
}
private void search(string path, string textToSearch, bool ignoreCase)
{
foreach (string currentFile in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
int lineNumber = 0;
foreach (string line in File.ReadLines(currentFile))
{
lineNumber++;
if (line.Contains(textToSearch))
{
lbFiles.Dispatcher.BeginInvoke((Action)(() =>
{
//add the file name and the line number to a ListBox
lbFiles.Items.Add(currentFile + " " + lineNumber);
}));
}
}
}
}
我的问题是,如果在文件中多次找到指定的字符串,则所有出现的行号都将是后者。对于包含以下行的文本文件:
abcdEFG
url
hijk123
url
列表框将如下所示:
当使用断点单步执行代码时,我可以看到,在退出搜索方法后,它会立即“跳回”到BeginInvoke
声明中。
请告知。
谢谢问题是您正在关闭变量行号
BeginInvoke
是异步的,它不等待在UI线程上调用委托。当它设法被调用时,lineNumber
已经增加了很多次
有两种解决办法。创建一个更本地化的lineNumber
副本以关闭,以便以后不会看到更改:
foreach (string line in File.ReadLines(currentFile))
{
lineNumber++;
if (line.Contains(textToSearch))
{
var lineNumberCopy = lineNumber;
lbFiles.Dispatcher.BeginInvoke((Action)(() =>
{
//add the file name and the line number to a ListBox
lbFiles.Items.Add(currentFile + " " + lineNumberCopy );
}));
}
}
或者使用Invoke
而不是BeginInvoke
,以便在行号有机会增加之前从中读取lineNumber
。这是预期行为BeginInvoke
创建异步操作并立即返回。