Как глобально обрабатывать исключения во всех потоках? [Дубликат]

Но иногда все в порядке! Например, если у вас есть фрагмент кода, который делает что-то «лишнее», что вам действительно неинтересно, и вы не хотите, чтобы оно взорвало ваше приложение. Например, недавно я работал над большим приложением, когда наши деловые партнеры хотели, чтобы определенная ежедневная транзакция была суммирована в новом файле журнала. Они объяснили, что журнал не так важен для них и что он не квалифицируется как требование. Это было что-то дополнительное, что помогло бы им понять обрабатываемые данные. Они им не нужны, потому что они могли получить информацию в другом месте. Таким образом, это редкий случай, когда прекрасно поймать и проглатывать исключения.

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

58
задан casperOne 19 October 2012 в 20:25
поделиться

2 ответа

77
ответ дан casperOne 28 August 2018 в 03:31
поделиться

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

using System;
using System.Threading.Tasks;

class FaFTaskFactory
{
    public static Task StartNew(Action action)
    {
        return Task.Factory.StartNew(action).ContinueWith(
            c =>
            {
                AggregateException exception = c.Exception;

                // Your Exception Handling Code
            },
            TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously
        ).ContinueWith(
            c =>
            {
                // Your task accomplishing Code
            },
            TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously
        );
    }

    public static Task StartNew(Action action, Action<Task> exception_handler, Action<Task> completion_handler)
    {
        return Task.Factory.StartNew(action).ContinueWith(
            exception_handler,
            TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously
        ).ContinueWith(
            completion_handler,
            TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously
        );
    }
};

Вы можете забыть об обработке исключений для задач, созданных с этого завода в вашем клиентском коде. В то же время вы все еще можете дождаться завершения таких Заданий или использовать их в стиле Fire-and-Forget:

var task1 = FaFTaskFactory.StartNew( () => { throw new NullReferenceException(); } );
var task2 = FaFTaskFactory.StartNew( () => { throw new NullReferenceException(); },
                                      c => {    Console.WriteLine("Exception!"); },
                                      c => {    Console.WriteLine("Success!"  ); } );

task1.Wait(); // You can omit this
task2.Wait(); // You can omit this

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

3
ответ дан ZarathustrA 28 August 2018 в 03:31
поделиться
Другие вопросы по тегам:

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