Исключение «Поток был прерван» во время отображения диалога - PullRequest
5 голосов
/ 21 октября 2008

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

Я получаю исключение "Поток был прерван" и совершенно не знаю, как от него избавиться. Я имею в виду поймать это исключение каким-либо образом или каким-либо другим способом скрыть его от пользователя. Это исключение не имеет ничего общего с остальной частью моего приложения, и эта ошибка никак не влияет на него. Появляется случайным образом, и восстановить его по вызову сложно.

Я пытался различными способами перехватить это исключение рядом с кодом, который запускает и останавливает поток с диалоговым окном, но кажется, что ошибка, по-видимому, связана с другим потоком, который выводит окно в моем недавно созданном потоке.

Вот пример кода, часть статического класса с полезными вещами, конечно, я не говорю, что это хороший способ решить такую ​​«занятую» ситуацию, но я хочу решить эту проблему. Thread.Sleep (500); или другие улучшения try / catch не помогают мне избежать этого исключения потока.

    public static bool alreadyBusy = false;
    public static BusyIndicator bi = new BusyIndicator("");
    public static Thread backgroundOpertionThread;

    public static void showBusy(bool isBusy, System.Windows.Forms.Form hostform, string message)
    {
        Common.busyMessage = message;
        if (isBusy)
        {
            Common.alreadyBusy = true;
            backgroundOpertionThread = new Thread(new ThreadStart(showBusy));
            Thread.Sleep(500);
            if (hostform != null)
            {
                hostform.Enabled = false;
                hostform.SuspendLayout();
            }
            backgroundOpertionThread.Start();

        }
        else
        {

            backgroundOpertionThread.Abort();
            Thread.Sleep(500);
            Common.alreadyBusy = false;
            if (hostform != null)
            {
                hostform.Enabled = true;
                hostform.ResumeLayout();
            }
        }
    }

    public static void showBusy()
    {
        BusyIndicator bir = new BusyIndicator(Common.busyMessage);
        bir.ShowDialog();
    }

Есть идеи?

Ответы [ 4 ]

15 голосов
/ 21 октября 2008

Do not использовать Thread.Abort. Этот метод зарезервирован для случаев, когда среде выполнения .NET необходимо принудительно уничтожать потоки, чтобы выгрузить вашу программу.

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

Чтобы избавиться от темы, запишите ее в кооперативном режиме. Это означает, что поток должен периодически проверять какой-либо флаг, и, если флаг установлен, обычно выходить из метода потока. Чтобы «убить» поток, просто установите флаг и дождитесь его завершения.

Вы можете использовать Event-объект или простую логическую переменную для этого флага.

Но не использовать Thread.Abort .

1 голос
/ 21 октября 2008

используйте SafeThread и установите для параметра AlwaysReportThreadAbort значение false, чтобы устранить проблему ...

лучшим решением было бы запустить его в отладчике с помощью команды Отладка >> Исключения >> Выброшено, проверено на наличие всех типов исключений и выяснить, что происходит, чтобы прервать поток

РЕДАКТИРОВАТЬ: спасибо за публикацию примера кода, что делает проблему намного легче увидеть. НЕ ВЫЗЫВАЙТЕ THREAD.ABORT

0 голосов
/ 21 октября 2008

Вы можете попробовать позвонить

Thread.Sleep(500);

после

backgroundOpertionThread.Start();

Это даст фоновому потоку 500 мсек, чтобы сделать то, что ему нужно сделать, прежде чем основной поток получит возможность вызвать

backgroundOpertionThread.Abort();

Редактировать: Но я согласен, что лучшим решением было бы вообще не использовать Thread.Abort ()

0 голосов
/ 21 октября 2008

Согласился с идеей Стивена о включении всех исключений при броске. Тогда вы сможете сразу увидеть проблему.

Одна вещь, которую важно помнить, у вас не будет опции меню отладки, если ваши настройки Visual Studio общие, в отличие от настройки «Visual C # Developer». Все еще ловит меня, если я на новой машине или использую новый профиль ...

...