VB.NET 最小化时应用程序冻结



我有一个由单个表单组成的Windows表单应用程序,该表单在单击几个按钮时解析大量文本。

有一大块代码可以解析XML文件的每个节点,通常大约有5000个节点包含20个左右的子节点,这些节点甚至有更多的子节点,依此类推,只是为了创建文件大小的图像。

在循环访问代码时,例如在解析数据时,如果我按下最小化按钮,它不会最小化,而是进入"无响应"状态。我的猜测是,在解析数据时无法处理最小化函数。

有没有办法为最小化/最大化/关闭按钮设置中断,或为它们设置优先级,或任何其他解决方案来实现表单的平滑最小化?

提前致谢

很抱歉添加与斯蒂芬几乎相同的答案,但等了 10 个小时让他删除DoEvents的东西。

数据收集或解析应在另一个线程中处理。最简单的方法是使用后台工作线程,并实现至少两个事件处理程序:

BGWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
' Move your parsing code here
' use local variables whenever possible
' do the appropriate changes
' and
BGWorker_RunWorkerCompleted( _
    ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
' tells your Main thread that it can use the resuls

注意:
您必须小心不要操作任何用户界面对象 在DoWork事件处理程序中。相反,与用户通信 通过ProgressChangedRunWorkerCompleted接口 事件。


我要补充一点:
您的 BGW 在其 DoWork 中需要的所有内容都应保持不变 (*) 任何其他代码。DoWork() 可以访问主线程中的任何内容(例如:操作 FileContent 的类实例、调用函数、读取静态变量......你不应该掉以轻心!由于干扰(如多个工作线程、状态更改或用户输入),这可能会产生意外行为。

应该处理干扰解析过程的用户输入:使用 .RunWorkerCompleted(..) 捕获主线程何时可以安全地(让用户)访问和操作数据、更改状态等。

(*) 最好的做法是在工作开始时将 BGW 所需的所有内容作为实际值的副本。如果你有一个很长的任务要做,并且在此期间可能会发生状态更改(例如:文件系统层次结构+文件删除 - 运行按时间排序结果的代码时日期更改...),您应该:

  • 请再想一想,代码中是否所有必需的工具都可用来正确完成任务(最佳情况)
  • 请仔细处理 RunWorkerCompletedEventArgs 参数的 .Error 属性(然后修复错误,然后重试。
  • 在使用数据之前验证数据完整性(最坏情况)

编辑:BGW不是唯一的方法。在遵循托管线程最佳实践建议的同时查看线程和线程。

由于您正在主线程中解析 XML,因此在解析完成之前,GUI 无法更新。最好的选择是使用后台工作者。它将启动另一个线程,允许您执行文件的解析,同时使 GUI 响应用户输入。

最新更新