C#4.0从Parallel.ForEach中访问表单控件
下面的代码运行正常。我不知道这是否真的正确C#4.0从Parallel.ForEach中访问表单控件,c#,winforms,parallel-processing,C#,Winforms,Parallel Processing,下面的代码运行正常。我不知道这是否真的正确 if (openFileDialog.ShowDialog() == DialogResult.OK) { Parallel.ForEach(openFileDialog.FileNames, currentFile => { try { StreamReader FileReader = new StreamReader(currentFile); do
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’”或应用程序被卡住。除非您在UI线程上进行marshall操作,否则无法从工作线程安全地更新UI控件 看看
代码是正确的-您需要使用
Invoke
从GUI线程外部刷新控件。但是,您正在执行SelectURLfromString(FileReader.ReadLine())method,您应该将其替换为
string url = SelectURLfromString(FileReader.ReadLine());
URLtextBox.Invoke(new MethodInvoker(delegate
{
URLtextBox.Text += url;
}));
将GUI线程中的工作最小化。调用是必要的,因为控件绑定到创建其关联User32窗口(通常称为HWND
)的线程。也就是说,您可能可以通过读取和处理调用
的委托之外的文件内容来进行一些优化。代码是正确的,您需要调用
以便在GUI线程中更新控件
但是,代码中还有其他一些东西没有真正意义:
- 您正在执行使用非并行资源的并行操作。你的线程将从磁盘上争夺注意力,这显然是瓶颈,因为它的速度相对较低
- 您将从多个文件中读取行,并将它们混合转储到文本框中。在这种特定情况下,这可能没问题,但通常会产生不可预测的结果
- 您正在使用
+=
操作来连接字符串,这种方法因可伸缩性差而臭名昭著。不过,在这种情况下,这可能不是一个大问题,因为磁盘瓶颈可能要严重得多