2010-08-17 2 views
0

Здравствуйте.System.Timers.Timer зависает, когда зависает пользовательский интерфейс в Windows XP

Вы, скорее всего, знаете, что System.Windows.Forms.Timer замораживает свое действие, когда поток пользовательского интерфейса также зависает, что происходит из-за того, что они запускаются в одном потоке.

Это заставило меня использовать System.Timers.Timer, который, в свою очередь, если пользовательский интерфейс замерзает, Timer продолжает запускать свой обычный процесс, как будто ничего не происходит.

Ну, мое приложение делает работу с IE, и время от времени IE замерзает при просмотре веб-сайта с плохим кодом Javascript. Вследствие этого также замораживается мой пользовательский интерфейс приложения вместе со всем приложением, потому что все в моем приложении работает на том же 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 секунд, как только истечет время его выполнения, который в свою очередь запускает delegatestatic method на другом Thread, который отвечает за прекращение IE, если он не отвечает.

Как я могу получить этот код, чтобы хорошо работать на Windows XP, как он работает на Windows 7.

Любая помощь приветствуется.

Спасибо.

EDIT:

Я также попытался 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 Thread не закрыл IE, и вот так я думал, что Thread не работает.

Так ведь. Проблема в том, как я могу найти, действительно ли процесс iexplore.exe отвечает или нет, не используя свойство Process.Responding?

Информация: Свойство Process.Responding для того, чтобы знать, если процесс отвечает требует Process.MainWindowHandle свойства, которое по какой-то причине, в соответствии с этим кодом sample, в Windows 7, что свойство существует, но не в Windows XP, там так Process.Responding также не работает на XP. Кто-нибудь знает обходное решение?

Aftermath: Учитывая, что на мой вопрос он ответил, я награжу одного ответственного за то, что он действительно помог мне найти то, что действительно было проблемой. Вопрос по этой проблеме продолжается here.

Спасибо всем.

ответ

4

Зачем использовать таймер вообще. Просто запустите второй поток и проверьте его каждые 15 секунд. Это будет проще и ниже.

Но если вы хотите сохранить таймер, возможно, класс System.Threading.Timer может обойти проблему.

+0

Я второй посвященный идея потока. Я был бы удивлен, если бы у System.Threading.Timer не было той же проблемы. В конце концов, это в основном основа «System.Timers.Timer». –

+0

Я склонен соглашаться на Threading.Timer, это просто попробовать. –

+0

Никогда не помешает попробовать :) –

1

В Windows 7 произошли существенные изменения в безопасности потоков для обработки системных ресурсов (например, переход от блокировки таблицы к блокировке строк в SQL). Вероятно, вы видите конкуренцию за какой-то системный ресурс, который блокируется в XP, но допускает множественные обращения в Win7. Учитывая, что не будет иметь значения, в какой поток работает ваш таймер, потому что все потоки будут блокироваться на одном ресурсе.

Возможно, если вы обнаружите, что это произошло в вашем приложении, вы можете открыть сообщение, предлагающее пользователю обновить свою ОС. :)

+0

@Jonh Bowen: Это приложение будет работать в загруженных виртуальных машинах с XP. Это должно было работать в XP. В этом нет обходного пути. –

Смежные вопросы