【发布时间】:2012-01-12 00:21:12
【问题描述】:
更多新手问题:
这段代码从主窗口的列表中抓取了一些代理(我不知道如何使变量在不同的函数之间可用)并检查每个代理(简单的httpwebrequest)然后添加将它们添加到一个名为 finishedProxies 的列表中。
由于某种原因,当我按下开始按钮时,整个程序挂断了。我的印象是 Parallel 会为每个操作创建单独的线程,让 UI 线程保持独立以便响应?
private void start_Click(object sender, RoutedEventArgs e)
{
// Populate a list of proxies
List<string> proxies = new List<string>();
List<string> finishedProxies = new List<string>();
foreach (string proxy in proxiesList.Items)
{
proxies.Add(proxy);
}
Parallel.ForEach<string>(proxies, (i) =>
{
string checkResult;
checkResult = checkProxy(i);
finishedProxies.Add(checkResult);
// update ui
/*
status.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(
delegate()
{
status.Content = "hello" + checkResult;
}
)); */
// update ui finished
//Console.WriteLine("[{0}] F({1}) = {2}", Thread.CurrentThread.Name, i, CalculateFibonacciNumber(i));
});
}
我尝试使用被注释掉的代码来更改Parallel.Foreach 内的 UI,它会在按下开始按钮后使程序冻结。它以前对我有用,但我使用了 Thread 类。
如何从 Parallel.Foreach 内部更新 UI 以及如何使 Parallel.Foreach 工作,以免 UI 在工作时冻结?
【问题讨论】:
-
你正在用调用请求来攻击 UI 线程,它不再有时间去做它的常规职责了。就像重绘 UI 一样。至少降低背景的优先级。
-
@dsp_099б 你在“它之前对我有用,但我使用了 Thread 类”下是什么意思?
-
任何其他人来这里:我怀疑这个例子甚至不应该使用 Parallel.ForEach。除非使用它有明显的好处,否则只需创建一个后台线程,然后在其中按顺序处理项目。然后任何返回 UI 线程的调用也将按顺序完成,避免同时请求使 UI 线程过载。 (或者使用更现代的解决方案,例如 async/await,它们也一次执行一个操作。)
标签: c# multithreading visual-studio-2010 user-interface task-parallel-library