- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个监视目录更改的应用程序。创建文件(日志文件)时,它会分析其内容,将结果写入表单(已经存在并已初始化,尽管当前可能隐藏),最后将此表单显示给用户。
应用程序启动时,任务栏中只会显示一个图标。 main 方法只是在任务栏中创建图标并初始化监视/分析和控制带有结果的表单的类。
public static void Main(string[] args) {
NotificationIcon notificationIcon = new NotificationIcon();
notificationIcon.notifyIcon.Visible = true;
if (notificationIcon.Init()) {
MainForm = ResultForm.GetInstance();
Application.Run();
}
}
“ResultForm”是我刚才提到的类,有以下与问题相关的方法:
public static ResultForm GetInstance() {
// _this is an attribute from the class. Is used to work always
// with just one instance of the classe
if (_this==null)
_this= new ResultForm();
return _this;
}
private ResultForm() {
// initialization of the GUI form
InitializeComponent();
[...]
// watcher for the log files
logsWatcher= new FileSystemWatcher(LOGFILES_FOLDER);
logsWatcher.Created += new FileSystemEventHandler(NewFile);
logsWatcher.EnableRaisingEvents=true;
logsWatcher.SynchronizingObject = this;
}
private void NewFile (object source, FileSystemEventArgs e) {
// make sure the file is of the correct type
[...]
// perform some analysis on the file
[...]
// update the contents in the form (some TreeViews and labels)
[...]
// show the form to the user
_this.Show();
}
现在问题来了。如果应用程序启动,分析了一个文件,还没有显示主窗体,分析完成后会显示为“Not responding”,虽然一切都已经完成了。如果之后创建了一个新文件,它将被成功分析,尽管表单将保持这种“未响应”状态。
但是,如果表单自应用程序启动后至少打开过一次(例如,您双击图标,显示表单,然后您将其关闭(或保持打开状态,这无关紧要)) ,一切都会顺利进行。
作为一种变通方法,我可以使用以下两行修改 main(在 Run()
方法之前),这样在任何文件到来之前该表单至少会显示一次:
MainForm.Show();
MainForm.Hide();
(我将它隐藏起来,因为在执行分析或用户明确单击该图标之前它不应该是可见的。)除此之外,程序没有区别:完成的工作是相同的,一旦完成所有操作,表格总是会显示。我已通过调试器确保在执行过程中已到达方法的末尾。
如果没有提到的解决方法,我该如何解决这个问题?
我已尝试使用 Application.DoEvents()
或类似于 this one 的代码块为分析创建线程.在最好的情况下,表单会正确显示其所有内容,但仍处于“未响应”状态。我还尝试只在方法中保留 Show()
调用,结果完全相同,这告诉我这不是重负载的问题,而是我可能做错了什么。
编辑由于@thecoon 提出要求,我上传了一个重现该问题的小项目。它已通过 SharpDevelop 完成,以防您也使用它。--> http://dl.dropbox.com/u/1153417/test.zip
在 Main() 方法中有一个小的解释。
最佳答案
我强烈怀疑这是一个线程问题,一个由您如何启动 ResultForm 以及如何设置 FileSystemObjects synchronization object 引起的问题.
同步对象有效地选择线程来编码更新。在这种情况下,它也是您试图在其上显示 GUI 的线程,因此您可能遇到了一个很好的旧阻塞操作,或者可能只是有大量文件系统事件导致您的线程来回上下文切换迅速。
作为初学者,试试这个:
public static void Main(string[] args) {
NotificationIcon notificationIcon = new NotificationIcon();
notificationIcon.notifyIcon.Visible = true;
if (notificationIcon.Init()) {
MainForm = new ResultForm();
Application.Run(MainForm);
}
}
请注意,我们现在将 ResultForm 直接编码到 UI 线程。
并以这种方式更改 ResultForm(也没有必要将其设为单例):
public ResultForm() {
// initialization of the GUI form
InitializeComponent();
[...]
this.Load += ResultForm_Load;
}
protected void ResultForm_Load(object sender, EventArgs e)
{
// watcher for the log files
logsWatcher= new FileSystemWatcher(LOGFILES_FOLDER);
logsWatcher.Created += new FileSystemEventHandler(NewFile);
logsWatcher.EnableRaisingEvents=true;
//Don't set the synchronization object - now all events from the FileSystemWatcher will be marshalled on a background thread
Visible = false; //Hide the form if you want or minimize to tray or similar.
}
private void NewFile (object source, FileSystemEventArgs e) {
if(InvokeRequired){
//Ensures the file system events are marshalled back to the GUI thread
Invoke(new MethodInvoker(() => {NewFile(source, e);}));
return;
}
// make sure the file is of the correct type
[...]
// perform some analysis on the file
[...]
// update the contents in the form (some TreeViews and labels)
[...]
// show the form to the user
Show(); //or Visible = true;
}
通过不将 FileSystemWatcher 上的同步对象设置为表单,您可以确保所有文件系统事件编码都将在 ThreadPool 线程中发生。当引发新事件时,我们只需记住通过检查 InvokeRequired 并在必要时调用表单的 Invoke 方法来编码回 UI 线程。
更新
主要原因是,通过直接调用 MainForm.Show 或通过 Application.Run(MainForm),您将表单推送到消息循环所在的线程上。
如果您使用原始代码运行应用程序,当调用 NewFile
时,Application.MessageLoop
为 false。
如果您使用变通方法或显示应用程序的标准方式,按照我的示例,Application.MessageLoop
为真。
我最好的猜测是表单死锁是因为 FileSystemWatcher(它在原始示例中使用表单作为同步对象,这实际上意味着它在表单上调用 BeginInvoke
) .但是,它也可能是各种各样的其他问题; Form.Show() 实际上卡在方法 FPushMessageLoop
上 - 它陷入无限循环。
@HansPassant 或@HenkHolterman 都围绕这些问题发表了大量文章 - 请参阅 https://stackoverflow.com/a/3833002/1073107例如。请注意,如果您在启动时显示启动画面或类似画面,则所有初始化都按预期工作,并且 NewFile 成功完成;简而言之,如果您希望流程正常运行,您必须在应用程序启动时显示一些内容。我不认为这是一件坏事;例如,用户可以看到应用程序已经启动并正在托盘中运行,您可以确定不会遇到此问题。
关于c# - 表格 "Not responding"如果之前没有显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11191864/
如何修复 Excel VBA 中的 Not Responding 错误? 我的代码是完美的,我没有收到任何错误,但在我运行它之后,我会看到 Excel VBA 的NOT RESPONDING 顶部并且
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: Keep app responsive during long task 在处理大型查询或长流程循环时如何避免“无响
这是我第一次遇到有人试图侵入我创建的网站。我可以做什么来阻止这些尝试? 顺便说一句,他们的 SQL 注入(inject)不可能起作用,而且我们拥有的任何数据都不能被正常使用该网站的任何人使用。 附加:
我的 java 进程停止响应。我尝试 jstack 但失败并出现以下错误。 21039: Unable to open socket file: target process not respondi
This question already has answers here: Closed 7 years ago. Possible Duplicate: Dismiss keyboard on
我不确定这是否重复,我尝试过的可能的补救措施无效。 (下面会提到) 我目前正在为我正在做的项目使用 Theme.AppCompat.NoActionBar 并且正在使用 android.support
这是一个简单的用户登录。我只是想了解这个概念。让我解释一下我的代码问题。这是我的表单: User: Password: check_login.php: Use
我正在创建一个线程,它可以控制所有程序过程消息并且不会卡住程序。我写了this code我得到了 program not responding。 有没有人有使用线程的经验可以帮助我? 最佳答案 Win
我将 Selenium 与 Python 结合使用。单击按钮时,我在 widows Python 中收到一条消息: Not responding in widows Python I have the
我有一个长时间运行的方法,必须在 UI 线程上运行。(Devex - gridView.CopyToClipboard()) 我不需要 UI 在复制时响应,我添加了启动画面,这样用户就不会感到无聊。
对于测试,使程序显示“无响应”的最简单方法是什么?中断 Windows 消息或将其置于无限循环中? 我试过一个简单的循环 while(true) 但这行不通。测试应用程序是 C# 控制台应用程序。它在
App里发生的最糟糕的事是弹出应用无响应”Application Not Responding” (ANR) 对话框.本课讲的是如何保持应用响应,避免ANR。 什么触发ANR 通常,系统会在应用
我们遇到一个客户运行我们基于 WPF 的程序的问题。他可以启动应用程序、创建新文档、在 TreeView 中导航菜单项以查看文档的不同部分、更改几乎(如果不是全部)我们的文本框值、将项目添加到列表(使
在VCL主线程中,我运行一个脚本,该脚本可能需要几分钟才能执行(这是一个还原数据库脚本)。 如果用户单击UI,则我的标题为“无响应”。 Application.ProcessMessages不起作用。
我这里有一个无意义的小脚本,我正在 MATLAB R2013b 中执行它: clear all; n = 2000; times = 50; i = 0; tCPU = tic; disp 'CPU:
我想将验证错误发送回另一个页面(添加),因此我的save操作具有以下功能: @Transactional(readOnly = false) def save(AddDomainCommand com
我正在构建一个 JavaFX 应用程序并使用 JOptionPane 来显示对话框 我遇到的问题之一是创建一个新对话框并且不在 5 秒左右关闭它会导致主 JavaFX 阶段进入“无响应”状态 在新线程
好吧,我尝试将信息从 servlet 发送到 jsp,所以我尝试使用 request.setAttribute() 和 respond.getRequestDispatcher("page.jsp")
我对代码进行排序有什么问题吗?当我打开程序时,我看到错误“程序未响应”。请检查我的代码。 void sorting(el_list **first) { el_list *newfirst =
出于测试目的,我需要编写一个程序,将著名的“应用程序未响应”消息显示在屏幕上。我不知道我怎么会激起这样的 react 。 最快、最简单的方法是什么?最好是 C/C++ 或 Java 最佳答案 在 Wi
我是一名优秀的程序员,十分优秀!