Здравствуйте.
Вы, скорее всего, знаете, что System.Windows.Forms.Timer
замораживает свое действие, когда поток пользовательского интерфейса также зависает, потому что они выполняются в одном потоке.
Это вынудило меня использовать System.Timers.Timer
, который, в свою очередь, если пользовательский интерфейс зависает, Timer
продолжает выполнять свой обычный процесс, как будто ничего не происходит.
Что ж, мое приложение выполняет большую часть работы с IE, и время от времени IE зависает при просмотре веб-сайта с плохим кодом Javascript. Как следствие, это также замораживает пользовательский интерфейс моего приложения вместе со всем приложением, потому что все в моем приложении работает на одном и том же Thread
. Чтобы противодействовать этой проблеме, мое приложение время от времени запускает простую проверку процессов IE, чтобы увидеть, отвечают ли они по-прежнему, и если они не прекращаются, все это в другом потоке.
Это противодействие отлично работает в 32-разрядной версии Windows 7, однако, когда я запускаю свое приложение на компьютере с 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 секунд, по истечении его времени выполняется метод, который, в свою очередь, запускает delegate
static method
на другом Thread
, который отвечает за завершение работы IE, если он не отвечает.
Как я могу заставить этот код хорошо работать в Windows XP, как он работает в Windows 7.
Любая помощь приветствуется.
Спасибо.
ИЗМЕНИТЬ:
Я также пробовал System.Threading.Timer
тот же результат, в Windows 7 работает, но не в Windows XP.
EDIT: следуя совету Кевина Гейла:
Я попытался использовать только Поток для противодействия и обнаружил, что не работает сам Поток. Это свойство 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();
}
Таким образом, поток выполняется каждые 15 секунд как в Windows 7, так и в XP. Но причина, по которой я думал, что это не работает, заключалась в том, что он не закрыл IE, когда он не отвечал.
И я обнаружил, что он не закрыл IE, потому что согласно exe.Responding
, который решает, отвечает ли процесс или нет, в Windows 7 он обнаруживает, что IE не отвечает, а в Windows XP он говорит, что IE отвечает, хотя на самом деле это нет. Вот почему в XP поток не закрывал IE, и поэтому я думал, что поток не работает.
Так ведь. Проблема в том, как я могу узнать, действительно ли процесс iexplore.exe
отвечает или нет, не используя свойство Process.Responding
?
Информация: Свойство Process.Responding
, чтобы узнать, отвечает ли процесс, требует свойства Process.MainWindowHandle
, которое по какой-то причине согласно этому коду sample, в Windows 7 это свойство существует, но не в Windows XP, поэтому Process.Responding
также не работает в XP . Кто-нибудь знает обходной путь?
Последствия: Учитывая, что на мой вопрос был дан ответ, я награждаю того, кто действительно помог мне найти то, что действительно было проблемой. Вопрос об этой проблеме продолжается здесь.
Спасибо всем.
System.Threading.Timer
не столкнулся с той же проблемой. В конце концов, это основаSystem.Timers.Timer
. 18.08.2010