我有一个相当密集的应用程序,我刚从控制台应用程序转换为Windows窗体应用程序。该计划基本上遍历了数千名客户,并根据他们的交付创建发票。对于每个交付和客户,信息将输出到控制台窗口 - 这意味着输出了大量信息!旧的过程需要多达20分钟,考虑到它正在做的规模,这是合理的。但我的经理和客户现在想把它作为Windows窗体。
我已实现了这一点,并输出了我作弊的信息并简单地替换了现有代码中的所有Console.WriteLine()调用来调用我的方法,追加给定的文本到Windows窗体上的TextBox。
我遇到了两个问题:
1:文本框偶尔会“冻结”并变为白色 - 但我认为我不能使用超过1个线程,因为我会定期在不同的线程上调用文本框
2:更严重的是,之前的20分钟过程需要更长的时间 - 大约4-5小时。我确信数据集没有被大幅放大,以便测试我们回滚到旧位置的所有代码,我能想到的唯一问题是我附加到文本框。我将在明天没有任何文本框写入测试以确认这一点,但代码没有以任何其他方式改变
是否还有其他更简单的方法可以将文本输出到Windows窗体,每秒多次?
答案 0 :(得分:5)
这里最好的选择是不要将所有数据直接输出到文本框中。
而是启动第二个线程来处理处理。每隔一段时间(20条记录?100?)将该线程与主线程同步,以更新某种类型的进度条。
让线程将正常的文本更新写入数据库或文本文件。
完成后,加载该文本文件并显示给用户。
几乎所有的额外时间都花在应用程序的主线程重绘表单上;这是一个昂贵的过程。当它这样做时,处理基本上被阻止(相同的线程)。由于文本框中的数据量增加,因此每次附加到文本框时,花费更新所花费的时间会线性增加...因此,10条记录不会发现太大的影响。 1000+将...取决于您要追加的数据量。
答案 1 :(得分:1)
我 建议使用工作线程,并进行线程安全回调以更新文本区域。
Microsoft在此提供了一个示例: http://msdn.microsoft.com/en-us/library/ms171728.aspx
您可能遇到的另一件事是每次更新时系统在文本框中重新创建字符串会产生大量开销。您需要限制执行此操作的频率,否则UI将无法跟上。
答案 2 :(得分:1)
你有几个问题:
Windows窗体具有线程关联性。这意味着所有写入都必须在UI线程上进行。如果您正在处理多个线程,请确保使用Control.Invoke
或Control.BeginInvoke
将回调编组回主线程。
随着文本变大,追加到TextBox中的字符串将逐渐变慢和变慢。尝试减少你做的追加数量。
就个人而言,我建议尝试以下方法:
使用BackgroundWorker
运行您的操作。您可以维护textToAppend
类型StringBuilder
变量,以便添加文本。定期(即:在进度更改处理程序中),将整个文本块附加到TextBox
(或RichTextBox
)控件。您可能需要通过锁定或其他机制同步对字符串构建器的访问,以防止发生竞争条件。
这将做两件事。首先,它将显着减少字符串连接操作的数量。这可能会让你失去很大一部分失速。它还将在操作运行时保持UI响应,因为该过程将在后台线程中执行。