【发布时间】:2011-03-31 05:28:58
【问题描述】:
你好。
您很可能知道System.Windows.Forms.Timer 会在用户界面线程也冻结时冻结其操作,这是因为它们在同一个线程中运行。
这迫使我使用System.Timers.Timer,如果用户界面冻结,Timer 会继续运行其通常的进程,就像什么都没发生一样。
好吧,我的应用程序在 IE 上做了很多工作,当浏览一个带有错误 Javascript 代码的网站时,IE 有时会死机。结果,这也冻结了我的应用程序用户界面以及所有应用程序,因为我的应用程序中的所有内容都在同一个Thread 上运行。为了解决这个问题,我的应用程序不时对 IE 进程运行一个简单的检查,以查看它们是否仍在响应,如果没有响应,它们将被终止,所有这些都在另一个线程上。
这个反作用在 Windows 7 32 位上运行完美,但是当我在 Windows XP 机器上运行我的应用程序时,反作用没有效果,可能是因为我的System.Timers.Timer 在用户界面冻结时也会冻结。一旦在另一个 Thread 上执行它就不应该发生这种情况,就像它不会在 Windows 7 上发生一样。
这是反作用过程的代码
private System.Timers.Timer IEResponsiveCheckTimer = new System.Timers.Timer();
private void onLoad(object sender, EventArgs e)
{
this.IEResponsiveCheckTimer.Interval = 15000;
this.IEResponsiveCheckTimer.Elapsed += new System.Timers.ElapsedEventHandler(IEResponsiveCheck);
this.IEResponsiveCheckTimer.Start();
}
private void IEResponsiveCheck(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(IEResponsiveChecker));
t.Start();
}
static void IEResponsiveChecker()
{
bool terminate = false;
foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses())
{
if (exe.ProcessName.StartsWith("iexplore"))
{
if (exe.Responding == false)
{
terminate = true;
break;
}
}
}
if (terminate == true)
{
foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses())
{
if (exe.ProcessName.StartsWith("iexplore"))
try { exe.Kill(); }
catch { }
}
}
}
这段代码非常简单。我们有一个Timers.Timer 每 15 秒运行一次,一旦它的时间过去了,就会执行一个方法,该方法反过来在另一个 Thread 上运行 delegate 的 Thread,如果他没有响应,它负责终止 IE。
我怎样才能让这段代码在 Windows XP 上像在 Windows 7 上一样运行良好。
感谢任何帮助。
谢谢。
编辑:
我也尝试了 System.Threading.Timer 相同的结果,在 Windows 7 中有效,但在 Windows XP 中无效。
编辑:遵循 Kevin Gale 的建议:
我尝试只使用线程来运行我的反作用,我发现不是线程本身不起作用。它的 Process.Responding 属性在 Windows XP 中无法正常工作。
新代码:
private void onLoad(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(IEResponsiveChecker));
t.Start();
}
static void IEResponsiveChecker()
{
bool terminate = false;
foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses())
{
if (exe.ProcessName.StartsWith("iexplore"))
{
if (exe.Responding == false)
{
terminate = true;
break;
}
}
}
if (terminate == true)
{
foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses())
{
if (exe.ProcessName.StartsWith("iexplore"))
try { exe.Kill(); }
catch { }
}
}
Thread.Sleep(15000);
IEResponsiveChecker();
}
这样,线程在 Windows 7 和 XP 上每 15 秒执行一次。但我认为它不起作用的原因是因为他没有在 IE 无响应时关闭它。
我发现他没有关闭 IE,因为根据exe.Responding 解决进程是否响应,在 Windows 7 中他检测到 IE 没有响应,在 Windows XP 中它说 IE 是回应虽然事实上它不是。这就是为什么在 XP 中 Thread 没有关闭 IE,所以我认为 Thread 不起作用。
毕竟。问题是如何在不使用 Process.Responding 属性的情况下找到进程 iexplore.exe 是否实际响应?
信息: 属性Process.Responding 以了解进程是否响应需要Process.MainWindowHandle 属性,根据此代码sample 出于某种原因,在Windows 7 中该属性存在但在 Windows XP 中不存在,因此Process.Responding 也不适用于 XP。有人知道解决方法吗?
后果:考虑到我的问题本身已经得到解答,我将奖励真正帮助我找到真正问题的负责人。该问题的问题继续here。
谢谢大家。
【问题讨论】:
标签: c# multithreading timer