Как я подавляю thread.abort () ошибка C#?

Согласно руководству по стилю PEP8 существует два способа форматирования словаря:

mydict = {
    'key': 'value',
    'key': 'value',
    ...
    }

ИЛИ

mydict = {
    'key': 'value',
    'key': 'value',
    ...
}

Если вы хотите соответствовать PEP8 Я бы сказал, что все остальное технически неправильно.

5
задан Refracted Paladin 4 June 2009 в 14:48
поделиться

7 ответов

Нет необходимости отменять поток. Я проиллюстрирую это кодом.

В форме экрана-заставки:

public void CloseSplash()
{
    Invoke((MethodInvoker)delegate
    {
        this.Close();
    });
}

В файле Program.cs:

private static Splash _splash = null;
public static void CloseSplash()
{
    if (_splash!= null)
    {
        _splash.CloseSplash();
    }
}

Теперь, когда ваш метод Main запускается, покажите заставку в потоке:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
    _splash.ShowDialog();
}));

t.Start();

... и когда вы хотите, чтобы он закрылся, просто закройте его:

Program.CloseSplash();

Тогда вам не нужно беспокоиться о прерывании потока; он завершится корректно.

20
ответ дан 18 December 2019 в 05:16
поделиться

См. Следующую ссылку, полученную при поиске в Google (возвращается первый результат):

http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx

Обратите особое внимание на эту часть:

Когда этот метод вызывается в потоке, система генерирует исключение ThreadAbortException в потоке, чтобы прервать его. ThreadAbortException - это специальное исключение, которое может быть перехвачено кодом приложения, но повторно генерируется в конце блока перехвата, если не вызывается ResetAbort . ResetAbort отменяет запрос на прерывание и предотвращает завершение потока ThreadAbortException . Неисполненные блоки finally выполняются до прерывания потока.

9
ответ дан 18 December 2019 в 05:16
поделиться

Использование Threadabort не рекомендуется. Это зло. Почему бы не использовать другой механизм, например (автоматический / ручной) ResetEvent? Запустите поток с заставки, дождитесь события. Если другой код завершил загрузку материала, установите событие en, ​​чтобы заставка закрывалась обычным (приятным) способом.

7
ответ дан 18 December 2019 в 05:16
поделиться

Некоторые моменты. Исключение ThreadAbort является причиной прерывания потока. Это не побочный эффект вызова прерывания. Когда вы вызываете прерывание в потоке, среда выполнения вынуждает передать исключение threadabort в поток. Это исключение может быть обнаружено, поскольку оно позволяет пользователю выполнить некоторую очистку перед прерыванием потока.

Затем исключение автоматически генерируется повторно, чтобы гарантировать, что поток был прерван. Если исключение было обнаружено и не было повторно инициировано, поток никогда не прервется.

На самом деле действительно интеллектуальный дизайн.

Так что действительно нормально поймать это исключение. На самом деле вы должны. Но ловите только это конкретное исключение, а не общее исключение. (как показано ниже)

catch(ThreadAbortException ex)
{
   //This is an expected exception. The thread is being aborted
}
4
ответ дан 18 December 2019 в 05:16
поделиться

Измените тип исключения на ThreadAbortException и добавьте вызов ResetAbort ()

    try
    {
        Program.splashThread.Abort();
    }
    catch(ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }

В общем, прерывание потоков считается очень плохой практикой и может привести к всевозможные баги, которые сложно выследить. Вы не думали найти способ просто закрыть окно-заставку или использовать какой-то опрос , чтобы остановить поток, когда установлен флаг?

3
ответ дан 18 December 2019 в 05:16
поделиться

Зачем вы это делаете? Просто установите флаг, который опрашивает поток, и, в конце концов, когда поток поднимет его, он закроется.

1
ответ дан 18 December 2019 в 05:16
поделиться

Я использовал решение, предложенное Фредриком Мёрком. Это очень четко и элегантно. В противном случае я обнаружил проблему, если мы создадим экземпляр всплывающей формы перед запуском реального приложения (application.run (mainform ...)):

он вызывает invalidOprationException, вызванную тем, что дескриптор формы все еще не существует в вызывающем потоке. Чтобы создать дескриптор непосредственно в потоке t (и пропустить это исключение!), Попробуйте запустить всплывающую форму следующим образом:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
     Application.Run(_splash);
}));

t.Start();

и, если вы планируете вызывать метод closeSplash в других ветвях программы, принудительно установите нулевое значение после первого вызова:

    private static Splash _splash = null;
    public static void CloseSplash()
    {
        if (_splash!= null)
        {
            _splash.CloseSplash();
            _splash=null;
        }
}
0
ответ дан 18 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: