Unhandled exception из Thread: как не валить процесс?
От: another_coder Россия  
Дата: 22.05.15 10:18
Оценка:
При возникновении unhandled exception в потоке, он завершается и еще завершает процесс.
Простой пример
public static void RaiseException(object state)
{
    Console.WriteLine("RaiseException");
    throw new Exception();
}

static void Main(string[] args)
{
    var d = new Thread(RaiseException);
    d.Start();
    Thread.Sleep(5000);
    Console.WriteLine("waiting...");
    Console.ReadKey();
}


Как запустить поток так, чтобы строка, выводящая "waiting" выполнилась и программа нормально завершилась?
Re: Unhandled exception из Thread: как не валить процесс?
От: Sinix  
Дата: 22.05.15 10:30
Оценка: +2
Здравствуйте, another_coder, Вы писали:

_>Как запустить поток так, чтобы строка, выводящая "waiting" выполнилась и программа нормально завершилась?

Обернуть запускаемый код в свой хелпер с try-catch. Чужой недоверенный код — вынести в отдельный домен/процесс (смотря насколько всё запущено).
Re: Unhandled exception из Thread: как не валить процесс?
От: tyomchick Россия  
Дата: 22.05.15 11:16
Оценка:
Здравствуйте, another_coder, Вы писали:

_>Как запустить поток так, чтобы строка, выводящая "waiting" выполнилась и программа нормально завершилась?


Или сделай обертку, как выше написали или запускай через:

Task.Run()

Тогда можно по свойству IsFaulted проверить, что завершилось по исключению и из свойства Exception взять объект исключения.
Даже самую простую задачу можно сделать невыполнимой, если провести достаточное количество совещаний
Re[2]: Unhandled exception из Thread: как не валить процесс?
От: another_coder Россия  
Дата: 22.05.15 11:18
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, another_coder, Вы писали:


_>>Как запустить поток так, чтобы строка, выводящая "waiting" выполнилась и программа нормально завершилась?

S>Обернуть запускаемый код в свой хелпер с try-catch. Чужой недоверенный код — вынести в отдельный домен/процесс (смотря насколько всё запущено).

Понятно. А так чтобы без try-catch? Хочется, чтобы поток умер просто, без остановки основного процесса. Я пробовал с AppDomain (запускал поток внутри созданного), но это не дало нужный мне результат. Вот так было:
        class A : MarshalByRefObject 
        {
            public void M()
            {
                var d = new Thread(RaiseException);
                d.Start();
            }

            public static void RaiseException(object state)
            {
                Console.WriteLine("RaiseException");
                throw new Exception();
            }
        }

        static void Main(string[] args)
        {
            var ads = new AppDomainSetup();
            ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            ads.DisallowBindingRedirects = false;
            ads.DisallowCodeDownload = false;
            ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            var ad = AppDomain.CreateDomain("AD", null, ads);

            A a = (A)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "A");
            a.M();

            
            Thread.Sleep(5000);
            Console.WriteLine("waiting...");
            Console.ReadKey();
        }
Re[3]: Unhandled exception из Thread: как не валить процесс?
От: Sinix  
Дата: 22.05.15 11:38
Оценка: +2
Здравствуйте, another_coder, Вы писали:

_>Понятно. А так чтобы без try-catch? Хочется, чтобы поток умер просто, без остановки основного процесса.

Простой неправильный ответ: запускать как Task, уже выше предложили. И про TaskCreationOptions.LongRunning не забыть. И про обработку исключений тоже.

Сложная ужасная правда: нет такого способа. Потому что в общем случае код может натворить что угодно, от StackOverflow и до Environment.FailFast(). Ну, или испортить состояние всей программы так, что нет никакого смысла продолжать работать. Так что обрабатываем исключение, спасаем всё что можно, падаем.
Re: Unhandled exception из Thread: как не валить процесс?
От: Iso12  
Дата: 22.05.15 22:09
Оценка:
Здравствуйте, another_coder, Вы писали:

_>При возникновении unhandled exception в потоке, он завершается и еще завершает процесс.
_>Как запустить поток так, чтобы строка, выводящая "waiting" выполнилась и программа нормально завершилась?


Вы бы написали,что конкретно хотите сделать.
Если вы "кидаете" исключение или при выполнении в потоке выскакивает исключение, то его, как тут уже подсказали, нужно обработать с помощью try ... catch .
Если вам надо просто передать состояние потока, например сигнализировать, что обработка в потоке закончена, то можно использовать для этих целей event and delegate или ManualResetEvent (в зависимости от потребностей).

Успехов
Re: Unhandled exception из Thread: как не валить процесс?
От: romangr Россия  
Дата: 25.05.15 06:34
Оценка:
Здравствуйте, another_coder, Вы писали:

_>При возникновении unhandled exception в потоке, он завершается и еще завершает процесс.

_>Простой пример
_>
_>public static void RaiseException(object state)
_>{
_>    Console.WriteLine("RaiseException");
_>    throw new Exception();
_>}

_>static void Main(string[] args)
_>{
_>    var d = new Thread(RaiseException);
_>    d.Start();
_>    Thread.Sleep(5000);
_>    Console.WriteLine("waiting...");
_>    Console.ReadKey();
_>}
_>


_>Как запустить поток так, чтобы строка, выводящая "waiting" выполнилась и программа нормально завершилась?


Есть еще один способ, но я бы не стал его рекомендовать.
в App.Config добавить:
    <runtime>
        <legacyUnhandledExceptionPolicy enabled="1"/>
    </runtime>
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 67>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.