【发布时间】:2016-11-03 23:36:49
【问题描述】:
我正在开发一个更大的程序,但它对列表框中的每个值执行的操作需要很长时间。我想通过对同一个列表视图框中的多个值执行相同的过程来加快速度,基本上是尝试添加某种类型的并行操作逻辑来完成工作。
我创建了一个快速程序,它是我正在工作的更大程序的一个非常非常简单的版本,我希望有人可以建设性地为我指明正确的方向。
有没有一种方法可以使用列表视图框,我可以同时从列表的顶部和底部开始,让每个人按照自己的方式工作,直到他们在中间相遇?我想不出另一种方法来做到这一点。
这是我现在与后台工作人员一起做的示例“代码”,没什么特别的(再次,这是一个模拟程序,因为我正在处理的实际程序的“复杂性”。)
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ListViewItem lst = listView1.SelectedItems[0];
foreach (ListViewItem user in listView1.Items)
{
MessageBox.Show(user.SubItems[0].Text);
}
}
private void button1_Click(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false; // I know, but this is an example program, so I'm using this for ny own sanity sake right now.
backgroundWorker1.RunWorkerAsync();
}
这是程序的 GUI 部分
我希望这是有道理的。如果没有,我可以进一步详细说明,但这是我想要做的事情的要点。
(我曾尝试在堆栈溢出中查找类似问题,但我没有发现这对我有帮助,因为它们要么使用不同的语言,要么因为它们超出了范围,所以我无法遵循我的程序,我不明白如何使他们的答案适应我的程序。)
更新有答案
如果这对将来有帮助,我接受了 cmets 中的建议,并在我的代码中实现了 Parallel.ForEach。因为它是一个列表视图,所以我的方法必须更有创意。
我的 ForEach 语句现在看起来像这样:
var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.50) * 1.0)) };
Parallel.ForEach<ListViewItem>(lstBackupUsers.Items.Cast<ListViewItem>(),opts, name => { // Long stuff to do here });
基本上,我在我的 backgroundworker 任务中删除了常规的“foreach”命令,并将其替换为上面的 Parallel.ForEach。作为参考,我不得不使用 ParallelOptions 来限制资源的数量(在这种情况下,我的资源的 50%。)
更新 2(有奇怪的问题)
所以上面的语句按预期工作并且运行良好,除了 Parallel.ForEach(...) 语句没有在我的整个列表框中重复当使用 MaxDegreeOfParallelism 参数时。如果我不在 ForEach 语句中使用它,那么我会收到“内存不足”异常,但如果我确实使用它,那么我的 ForEach 会运行几行然后它就会停止。
是这样的(对我来说):
如果我设置 MaxDegreeOfParallelism,它只会通过我的机器中的内核数与列表视图框重复(无论我告诉 MaxDegreeOfParallelism 使用什么值。)例如:
我有一个包含 20 行的列表视图框,我的计算机只重复其中 8 个然后 ForEach 停止(我的机器现在有 8 个内核。)
知道我还能做什么吗?
谢谢!
更新 3
我现在有var result = Parallel.ForEach,我正在检查result.IsCompleted,这帮助我找到了解决循环的正确方向。
【问题讨论】:
-
你试过使用
Parallel.ForEach吗? -
谢谢 gilmishal,我没看过。哎呀..点击返回有点太快了。所以我会做类似
ListViewItem userList<ListViewItem> username = new List<ListViewItem>(user)然后Parallel.ForEach(username, row => { // background_dowork stuff here? }); -
如果您同时执行所有这些任务,那么 "我可以从顶部和底部开始吗..." 不会为解决方案添加任何内容。
-
我希望它可以通过一次处理 2 个用户而不是一次处理一个用户来加速程序。如果程序从列表框的顶部和底部开始,这个逻辑是否不正确(向上)同时?
标签: c# winforms parallel-processing