Но иногда все в порядке! Например, если у вас есть фрагмент кода, который делает что-то «лишнее», что вам действительно неинтересно, и вы не хотите, чтобы оно взорвало ваше приложение. Например, недавно я работал над большим приложением, когда наши деловые партнеры хотели, чтобы определенная ежедневная транзакция была суммирована в новом файле журнала. Они объяснили, что журнал не так важен для них и что он не квалифицируется как требование. Это было что-то дополнительное, что помогло бы им понять обрабатываемые данные. Они им не нужны, потому что они могли получить информацию в другом месте. Таким образом, это редкий случай, когда прекрасно поймать и проглатывать исключения.
Я также работал в компании, где все Throwables были пойманы, а затем повторно встроены в пользовательское исключение RuntimeException. Я бы не рекомендовал этот подход, а просто указал, что это сделано.
Вы можете создать какую-то пользовательскую фабрику задач, которая создаст 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
Но если честно, я не совсем уверен, почему вы хотите иметь обработку завершения код. В любом случае это решение зависит от логики вашего приложения.