【问题标题】:Adding controls to winform while allowing user to enter input在允许用户输入输入的同时向winform添加控件
【发布时间】:2011-07-27 20:18:35
【问题描述】:

我有一个 WinForms 数据输入表单,其中包含超过 1500 个问题。我将问题分成几个部分,每个部分都有未知数量的问题。每个部分都是自己的用户控件,并为每个问题动态创建和添加行(2 个面板、2 个标签、一个文本框和另一个用户控件)。然后将部分控件添加到表单中。

我的问题是该过程需要很多时间,即使使用 TPL(任务并行库)也是如此。我最终希望创建/添加控件并允许用户同时开始输入数据。控件将进入可滚动面板。当用户输入数据时,这些数据需要在本地数据库中处理……因此可能需要更多线程。

我尝试过使用 TPL,我是新手,在处理过程中将所有控件添加到列表中,然后在 Parallel.ForEach 完成后排序并添加到表单中...大约需要 20 秒超过 1200 个问题。

我还尝试使用BackgroundWorker 组件。使用 BWC 似乎是两者中较快的,但 ProgressChanged() 事件处理程序存在竞争条件,并且并非所有控件都被添加......更不用说表单在所有重新呈现时的外观。

我只是用错了 TPL 吗?解决这个问题的最佳方法是什么?还有其他方法还是我只是让用户等待?

谢谢

【问题讨论】:

  • 这与线程无关。当您拥有这么多控件时,只需绘制表单就需要很长时间。它太大了,超过 10 倍。
  • @Hans Passant:是的,我同意表格太大。不幸的是,这是我无法控制的。
  • 这将导致项目灾难。至少让利益相关者知道他会期待什么。 “不是我的问题”的态度不会让任何人开心,它会成为你的问题。
  • @Hans Passant:我从来没有说过我采取“不是我的问题”的态度。每个人都充分意识到这个问题,这不是一个好的做法。如您所见,这已经是我的问题了。

标签: winforms multithreading c#-4.0 task-parallel-library


【解决方案1】:

我只是用错了 TPL 吗?解决这个问题的最佳方法是什么?还有其他方法还是我只是让用户等待?

很可能,您可以使用 TPL,并获得与 BW 相同的响应时间,但为此类操作提供更好的 API。

这里的技巧是为 UI 交互设置一个 TaskScheduler,然后使用 Task 类在控件准备好时将它们推回 UI 线程。我有一个blog post on this specific subject,它展示了如何让 TaskScheduler 设置与 UI 线程一起使用。

但是,我建议将它们保存在内存中并分批推送,以避免不断地重新渲染 UI。无论您在做什么,这都可能是一个问题。

话虽如此 - 我会在这里质疑您的整体视觉设计 - 如果您尝试向用户显示超过 1200 个问题,那么某种形式的分页可能比巨大的可滚动容器更好。如果您分页,您可以加载和处理前几个问题(这可能几乎是瞬时的,因为您提到您可以处理大约 50 个问题/秒),然后在前几个问题显示后继续加载其他问题。

【讨论】:

  • 我同意更好的 UI 设计是拆分部分,这是我的建议,但规格和客户另有规定。
  • @jonnyltunes:那么我建议使用 Task/Task 和批处理。我上面的博文(以及之前的几篇文章)展示了基本方法。
  • @Reed Copsey:不错的博文!我关注了您的博客并将控件编组到 UI 线程。但是,似乎尽管为创建控件的过程创建了Task 并使用了BeginInvokeEndInvoke,但主线程仍然被阻塞。有任何想法吗?我什至放了一个线程睡眠者来中断处理。
  • @Jonnyltunes:你是如何开始这项任务的?你是在调用 Task.Wait() 还是 Task.Result? [阻止...]
  • @Reed Copsey:感谢您的回复。我使用TaskScheduler.FromCurrentSynchronizationContext()new TaskFactory(uiScheduler) 创建了一个TaskScheduler。然后我调用uiTaskFactory.StartNew(() => ProcessSections(Sections));Sections 是在此步骤之前生成的列表对象。此时,我只是尝试创建控件并将它们添加到队列中,而没有添加任何到窗体,并且主线程仍然被阻塞。我不使用Task.Wait()Task.Result。我的部分列表中的项目是属性和EntityObjects 的组合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 2017-08-30
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多