从数据库中获取数据时,WinForms应用程序似乎“无响应”?

时间:2011-01-29 12:04:03

标签: .net database winforms fetch

我在处理CRUD操作的WinForms应用程序(VB.NET)上工作。 当它加载数据时,似乎状态为“无响应”,加载完成后,每件事都会正常。

当表单从数据库中获取记录时,如何解决类似的问题?

非常感谢。

3 个答案:

答案 0 :(得分:5)

您可以使用BackgroundWorker在后台线程上卸载冗长的操作,以避免阻塞主UI线程。

答案 1 :(得分:2)

所有Windows应用程序都是如此,如果您从事件中执行任何长度操作,您将在一段时间内“无响应”,因为程序没有响应系统的其余部分。你有几个选择:

  • Application.DoEvents,如果你有一个包含许多离散快速操作的循环,并且每次操作后都有DoEvents
  • 通过Threads或BackgroundWorker将任务推送到后台。

如果您将使用第二个选项,请确保您不直接在UI上更新任何内容,因为它会中断,而是使用Invoke()。

答案 2 :(得分:1)

如果您使用的是单一界面,则最好使用Application.DoEvents()。如果您有一个表单在单击按钮时执行一系列任务,那么您将使用单个界面。

为什么选择Application.DoEvents()?

From the MSDN page on DoEvents()

  

运行Windows窗体时,它会创建新窗体,然后等待事件处理。每次表单处理事件时,它都会处理与该事件相关的所有代码。所有其他事件在队列中等待。当您的代码处理事件时,您的应用程序不会响应。例如,如果在顶部拖动另一个窗口,窗口不会重新绘制。

     

如果您在代码中调用DoEvents,您的应用程序可以处理其他事件。例如,如果您有一个表单将数据添加到ListBox并将DoEvents添加到您的代码中,那么当另一个窗口被拖动时,您的表单将重新绘制。如果从代码中删除DoEvents,则在按钮的单击事件处理程序执行完毕之前,表单将不会重新绘制。有关消息传递的详细信息,请参阅Windows窗体中的用户输入。

简而言之,如果您单击按钮并且必须等待完成某些工作,Application.DoEvents()将刷新表单UI并摆脱(无响应)问题。

如何使用DoEvents() 相同的MSDN页面也说明了

  

通常,您在循环中使用此方法来处理消息。

因此,告诉它应该去哪里的最简单方法是在程序中寻找一个循环,在该循环中发生冗长的操作并将Application.DoEvents()放在该循环中。我通常将它放在所述循环内的最后。

例如:

foreach (var foo in bar)
  {
    // Do work
    Application.DoEvents();
  }

为什么不使用单一界面的BackgroundWorker?

当您创建不需要多线程的多个线程时,您可能会出现线程泄漏的可能性。例如,如果您实现BackgroundWorker来处理CRUD操作,但由于某种原因,关闭程序,接口将关闭但后台工作程序线程将继续运行。您可以通过任务管理器确认此过程仍在运行。

当您有其他正在使用的设备(如打印机)时,BackgroundWorkers非常理想。也就是说,您可能不希望程序在完成打印文档之前停止;因此,在您继续使用程序时,新线程可以处理打印作业。