向 winform 添加控件,同时允许用户输入
我有一个 WinForms 数据输入表单,其中包含超过 1500 个问题。我将问题分成几个部分,每个部分都有未知数量的问题。每个部分都是其自己的用户控件,并为每个问题动态创建和添加行(2 个面板、2 个标签、一个文本框和另一个用户控件)。然后将部分控件添加到表单中。
我的问题是,即使使用 TPL(任务并行库),该过程也需要花费大量时间。我最终想创建/添加控件并允许用户同时开始输入数据。控件将进入可滚动面板。当用户输入数据时,该数据需要在本地数据库上处理......因此可能需要更多线程。
我尝试过使用 TPL(我是新手),方法是在处理过程中将所有控件添加到列表中,然后在 Parallel.ForEach 完成后排序并添加到表单中...大约 20 秒回答 1200 多个问题。
我还尝试使用 BackgroundWorker
组件。使用 BWC 似乎是两者中更快的一个,但是 ProgressChanged()
事件处理程序存在竞争条件,并且并非所有控件都会添加......更不用说表单在所有控件中的外观了重新渲染。
我只是错误地使用了 TPL 吗?解决这个问题的最佳方法是什么?有没有其他方法或者我只是让用户等待?
谢谢
I have a WinForms data entry form that will have upwards of 1500 questions. I have the questions broken into sections, and each section will have an unkown number of questions. Each section is its own user control and has rows (2 panels, 2 labels, a textbox, and another user control) created and added dynamically for each question. The section controls are then added to the form.
My problem is that the process takes a lot of time, even with using TPL (Task Parallel Library). I would ultimately like to create/add the controls and allow the user to start entering data at the same time. The controls are going into a scrollable panel. While the user is entering data, that data will need processed on a local database...so more threading could be necessary.
I have tried working with TPL, which I am new to, by having all the controls added to a list during processing and then sorted and added to the form after the Parallel.ForEach
was complete...takes about 20 seconds for over 1200 questions.
I also tried utilizing a BackgroundWorker
component. Using the BWC seems to be the faster of the two, but there is a race condition for the ProgressChanged()
eventhandler and not all controls get added...not to mention the way the form looks with all the rerendering.
Am i just using TPL wrong? What's the best way to go about this? Is there another way or do I just make the user stick out the wait?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最有可能的是,您可以使用 TPL,并获得与 BW 相同的响应时间,但对于此类操作有更好的 API。
这里的技巧是获取用于 UI 交互的 TaskScheduler 设置,然后使用 Task 类在控件准备好时将其推回 UI 线程。我有一个 关于此特定主题的博客文章,其中展示了如何获取与 UI 线程一起使用的 TaskScheduler 设置。
不过,我建议将它们保留在内存中并分批推送,以避免不断重新渲染 UI。无论您在做什么,这都可能是一个问题。
话虽这么说 - 我会在这里质疑你的整体视觉设计 - 如果你试图向用户显示超过 1200 个问题,某种形式的分页可能是比巨大的可滚动容器更好的方法。如果您对这些进行分页,则可以加载并处理前几个问题(这可能几乎是瞬时的,因为您提到每秒可以处理大约 50 个问题),然后在显示前几个问题后继续加载其他问题。
Most likely, you can use TPL, and get the same response time as BW, but a nicer API for this type of operation.
The trick here is to get a TaskScheduler setup for UI interaction, and then use the Task class to push the controls back onto the UI thread as they're ready. I have a blog post on this specific subject which shows how to get a TaskScheduler setup to use with UI threads.
However, I would recommend keeping these in memory and pushing them in batches, to avoid constantly re-rendering the UI. This is likely to be an issue no matter what you're doing.
That being said - I'd question your overall visual design here - if you're trying to display over 1200 questions to the user, some form of paging is probably a much nicer approach than a huge scrollable container. If you page these, you could load and process the first few (which is probably near instantaneous, since you mentioned you can process about 50 questions/second), and then continue loading the others after the first few questions have been displayed.