为什么这个 Parallel.ForEach 代码会冻结程序? [英] Why does this Parallel.ForEach code freeze the program up?

查看:20
本文介绍了为什么这个 Parallel.ForEach 代码会冻结程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更多新手问题:

这段代码从主窗口的列表中抓取了一些代理(我不知道如何使变量在不同的函数之间可用)并对每个代理进行检查(简单的 httpwebrequest) 然后将它们添加到名为 finishedProxies 的列表中.

This code grabs a number of proxies from the list in the main window (I couldn't figure out how to make variables be available between different functions) and does a check on each one (simple httpwebrequest) and then adds them to a list called finishedProxies.

由于某种原因,当我按下开始按钮时,整个程序都挂了.我的印象是 Parallel 为每个操作创建单独的线程,而单独留下 UI 线程,以便它具有响应性?

For some reason when I press the start button, the whole program hangs up. I was under the impression that Parallel creates separate threads for each action leaving the UI thread alone so that it's responsive?

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 类.

I've tried using the code that's commented out to make changes to the UI inside the Parallel.Foreach and it makes the program freeze after the start button is pressed. It's worked for me before but I used Thread class.

如何从 Parallel.Foreach 内部更新 UI 以及如何使 Parallel.Foreach 工作,以便它不会使 UI 冻结有效果吗?

How can I update the UI from inside the Parallel.Foreach and how do I make Parallel.Foreach work so that it doesn't make the UI freeze up while it's working?

这是完整的代码.

推荐答案

不得在 UI 线程中启动并行处理.请参阅此页面中避免在 UI 线程上执行并行循环"标题下的示例.

You must not start the parallel processing in your UI thread. See the example under the "Avoid Executing Parallel Loops on the UI Thread" header in this page.

更新:或者,您可以简单地手动创建一个新线程并在其中开始处理,就像我看到的那样.这也没什么不对.

Update: Or, you can simply create a new thread manuall and start the processing inside that as I see you have done. There's nothing wrong with that too.

此外,正如 Jim Mischel 指出的,您同时从多个线程访问列表,因此存在竞争条件.将 ConcurrentBag 替换为 List,或者每次访问列表时将列表包装在 lock 语句中.

Also, as Jim Mischel points out, you are accessing the lists from multiple threads at the same time, so there are race conditions there. Either substitute ConcurrentBag for List, or wrap the lists inside a lock statement each time you access them.

这篇关于为什么这个 Parallel.ForEach 代码会冻结程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆