[英]C# 4.0 Accessing form control from within Parallel.ForEach
下面的代码运行正常。 我想知道它是否真的正确?
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
Parallel.ForEach(openFileDialog.FileNames, currentFile =>
{
try
{
StreamReader FileReader = new StreamReader(currentFile);
do
{
URLtextBox.Invoke(new MethodInvoker(delegate
{
URLtextBox.Text += SelectURLfromString(FileReader.ReadLine());
}));
}
while (FileReader.Peek() != -1);
FileReader.Close();
}
catch (System.Security.SecurityException ex)
{
...
}
catch (Exception ex)
{
...
}
});
}
否则我得到“跨线程操作无效。控制'URLtextBox'从另一个线程访问”或卡住应用程序。
代码是正确的 - 您需要使用Invoke
从GUI线程外部刷新控件。 但是,您正在SelectURLfromString(FileReader.ReadLine());
在GUI线程中的方法,你应该替换它
string url = SelectURLfromString(FileReader.ReadLine());
URLtextBox.Invoke(new MethodInvoker(delegate
{
URLtextBox.Text += url;
}));
尽量减少GUI线程中的工作。
代码是正确的,您需要Invoke
以便在GUI线程中更新控件。
但是,还有一些其他的东西在代码中没有意义:
您正在执行使用非并行资源的并行操作。 你的线程将争夺磁盘的注意力,因为它的速度相对较低,显然是瓶颈。
您将从多个文件中读取行,并将它们混合在一个文本框中。 在这种特定情况下,这可能是正常的,但通常会产生不可预测的结果。
您正在使用+=
操作来连接字符串,这种方法因其糟糕的可伸缩性而臭名昭着。 在这种情况下,这可能不是一个大问题,因为磁盘瓶颈可能要糟糕得多。
Invoke是必需的,因为控件绑定到创建其关联User32窗口(通常称为HWND
)的线程。 也就是说,您可以通过在Invoke
的委托之外读取和处理文件的内容来优化一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.