是否可以检测到应用程序何时停止响应,因此可以自动采取适当的操作,而不是用户必须转到任务管理器/结束进程和/或结束任务等?
答案 0 :(得分:2)
您应该尝试让您的应用程序不要停止响应。
这样做的一种方法是在不同的线程中启动那些复杂的任务,并在超时后杀死它。
答案 1 :(得分:2)
请耐心等待 - 这不是你问题的直接答案,而是一些设计建议,以避免陷入你的境地。如果您的应用程序真的被锁定而没有响应,则无法检测到它并做出响应。诀窍是避免一开始就陷入困境。
根据我的经验,WinForms应用程序几乎从不停止响应。相反,它们在执行长时间运行的任务或陷入无限(或至少长时间运行)的循环时往往表现得没有反应。
您可以使用多线程技术将长时间运行的进程放在另一个线程中来避免这种情况。适用于长时间运行循环的缓动技巧是放置代码
Application.DoEvents()
循环内部。这将允许应用程序在循环运行时显示响应,此时它通常会显示为已锁定。
我通常处理这种情况的方法是通过一个状态标签,我不断更新,让用户知道应用程序正在执行如下所示的操作:
foreach(DataRow r in myTable.Rows)
{
StatusLabel.Text = "Now processing " + r[0].ToString();
Application.DoEvents();
... now do the real work
}
这为用户提供反馈,让他们知道应用实际上在做什么,而不仅仅是“锁定”。 99%的时间,用户的感知是最重要的。
编辑 - 已添加以回复以下评论
Application.DoEvents() 确实 包含性能损失。你需要决定它是否值得。正如我上面所示(与某种进度指示器结合使用),它可以消除用户的挫败感,并且我发现它对于长时间运行的过程是值得的权衡。
我的原始答案提到了99%的时间都是重要的。我将举例说明我在哪里使用它并认为它是合理的。
我继承了我的一位前任编写的WinForms应用程序。该应用程序有一个过程需要每周完成,以汇总和处理数百万条记录。除了大量记录之外,数据库设计不当,因此该过程花费了一个多小时。因此,用户将被困在他们的计算机上一小时,看着这个屏幕什么都不做。他们无法知道应用程序是否真的有效。我将上面的代码添加为临时措施,最终用户非常感激。他真的很感激知道应用程序真的有用而且不仅仅是挂断了。
添加application.DoEvents()会使处理时间从一小时增加到一小时五分钟左右。这是一个明显的减速,但用户对它感到高兴,因为即使花了更长的时间,他也知道它在做什么。
顺便说一句,它让我更快乐,因为偶尔,由于异常高的记录计数需要更长的时间,用户在程序上结束任务并重新运行它认为它被锁定,这将不可避免地导致我不得不花费数小时来修复数据。
作为最后一点,我从头开始重新编写应用程序,包括重新设计数据库,同样的过程需要5秒钟。我添加这不是为了吹嘘,而是为了让你思考为什么你的应用程序似乎锁定。如果您能够以更高效的方式完成任务并获得更好的设计,那么在很多情况下都可以完全避免这种情况。
答案 2 :(得分:1)
你能做的最多就是计算一个操作需要多长时间,如果花了太长时间,就把它杀掉。当然,操作必须具有类似CancelEventArgs
的内容,主应用程序可以订阅和调用。
另一种方法是在一个单独的线程中启动操作,并在主线程中,记住该线程运行的时间长度,如果花费的时间太长,则将其终止。
答案 3 :(得分:0)
我会这样做:在主线程中定时触发定时器,将计数器重置为0.然后,在另一个线程中,有另一个计时器递增计数器。当计数器达到某个值时,表示主线程已停止响应一段时间。