Hello.
You most likely are aware that a System.Windows.Forms.Timer
freezes its action when the user interface thread also freezes, that happens because they run in the same thread.
That forced me to use a System.Timers.Timer
which in turn if the user interface freezes the Timer
continues to run its usual process like nothing ever happen.
Well my application does a allot of work with IE, and from time to time IE freezes when browsing a website with bad Javascript code. In consequence that also freezes my application user interface along with all the application, because everything in my application runs on the same Thread
. To counteract that problem, my application from time to time runs a simple check on IE process's to see if they are still responding and if they don't they are terminated, all that on another Thread.
This counteraction runs perfect on Windows 7 32 bits, however when i run my application on a Windows XP machine that counteraction has no effect, maybe because my System.Timers.Timer
also freezes when the user interface freezes. Which it shouldn't happen once its executed on another Thread
like it doesn't happen on Windows 7.
Here is the code for the counteraction process
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 开发者_StackOverflow= 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 { }
}
}
}
This code is pretty simple. We have a Timers.Timer
running every 15 seconds, once its time elapses a method is executed which in turn runs the delegate
of a static method
on another Thread
which is responsible to terminate IE if he isn't responding.
How can i get this code to run well on Windows XP like it runs on Windows 7.
Any help is appreciated.
Thanks.
EDIT:
I also tried a System.Threading.Timer
same result, in Windows 7 works but not in Windows XP.
EDIT: Following Kevin Gale advice:
I've attempted using only the Thread to run my counteraction, and i have found that it isn't the Thread it self that isn't working. Its the Process.Responding
property that isn't working well in Windows XP.
New Code:
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();
}
This way the Thread is executed every 15 seconds on both Windows 7 and XP. But the reason i thought it wasn't working, was because he didn't close IE when it was unresponsive.
And I've found he didn't closed IE because according to exe.Responding
which resolves if the process is responding or not, in Windows 7 he detects that IE isn't responding and in Windows XP it say that IE is responding although in fact it isn't. Thats why in XP the Thread didn't closed IE, and there so i thought the Thread didn't work.
So after all. The problem is how can i find if the process iexplore.exe
is actually responding or not without using the Process.Responding
property?
Info: The property Process.Responding
in order to know if the process is responding requires the Process.MainWindowHandle
property, which for some reason according to this code sample, in Windows 7 that property exists but not in Windows XP, there so Process.Responding
also doesn't work on XP. Anybody knows a workaround?
Aftermath: Considering that my question it self has been answered, i will award the one responsible to truly helping me finding what was really the problem. The question for that problem continues here.
Thanks everyone.
Why use a timer at all. Just start the second thread and have it check every 15 seconds. That would be simpler and lower overhead.
But if you want to keep the timer maybe the System.Threading.Timer class might get around the problem.
Windows 7 made some major changes in thread safety for handling of system resources (like going from table locking to row locking in SQL). You're probably seeing contention for some system resource that blocks in XP but allows multiple accesses in Win7. Given that, it's not going to matter what thread your timer is running on because all of the threads will block on the same resource.
Maybe if you detect that this has happened in your app you could pop up a message suggesting the user upgrade their OS. :)
精彩评论