Nano Hash - криптовалюты, майнинг, программирование

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

Здравствуйте.

Вы, скорее всего, знаете, что 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 . Кто-нибудь знает обходной путь?

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

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

17.08.2010

Ответы:


1

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

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

17.08.2010
  • Я поддерживаю идею специальной темы. Я был бы удивлен, если бы System.Threading.Timer не столкнулся с той же проблемой. В конце концов, это основа System.Timers.Timer. 18.08.2010
  • Я склонен согласиться с Threading.Timer, это просто то, что нужно попробовать. 18.08.2010
  • Я новичок в C# Threading. Как вы предлагаете сделать это без использования таймера и при этом запускать поток каждые 15 секунд? @Brian Gideon: я попробую с Threading.Timer, может мне повезет;) 18.08.2010
  • Извините, что не ответил вам раньше, и я вижу, что на другой вопрос был дан ответ. Единственный комментарий, который у меня есть по поводу приведенного выше отредактированного кода, заключается в том, что вы должны использовать цикл вместо рекурсивного вызова IEResponsiveChecker(). 23.08.2010

  • 2

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

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

    17.08.2010
  • @Jonh Bowen: Это приложение будет работать на множестве виртуальных машин под управлением XP. Оно должно было работать в XP. Обходного пути по этому поводу нет. 18.08.2010
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..