С# try catch continue execute
У меня есть вопрос, который может показаться довольно простым (конечно, если вы знаете ответ).
У определенной функции у меня есть другая функция, но я хочу продолжить выполнение от вызывающего, даже если вызываемый вызывал исключение. Позвольте мне привести вам пример:
something function1()
{
try
{
//some code
int idNumber = function2();
//other code that need to execute even if function2 fails
return something;
}
catch(Exception e)
{//... perhaps something here}
}
EDIT: function1 также имеет оператор return, поэтому ничто не может на самом деле сбой на пути
В функции2 мне нужно делать что-то, но мне нужно только регистрировать, если что-то не получается, например:
int function2()
{
try
{
//dostuff
}
catch(Exception e)
{
//Log stuff to db
}
}
ok, теперь мой вопрос: что мне делать, если я хочу продолжить выполнение в функции1, даже если функция 2 выдает ошибку?
Иногда я смешиваю, если мне нужно бросить; или выбросить e; или вообще ничего не бросать (оставляйте блокировку catch пустым)
Ответы
Ответ 1
Если оставить блок catch пустым, он должен сделать трюк. Это почти всегда плохая идея. С одной стороны, существует штраф за исполнение, а с другой (и это более важно), вы всегда хотите знать, когда есть ошибка.
Я бы предположил, что функция "вызываемого" в вашем случае не может быть "ошибкой", так сказать, на самом деле. То есть ожидается, что он будет иногда терпеть неудачу. Если это так, всегда есть лучший способ справиться с этим, чем использовать исключения.
Есть, если вы помиловете каламбур, исключения в "правило". Например, если функция2 должна была вызвать веб-службу, результаты которой на самом деле не нужны для вашей страницы, такой тип шаблона может быть в порядке. Хотя почти в 100% случаев вы должны, по крайней мере, регистрировать его где-то. В этом случае я должен был зарегистрировать его в блоке finally
и сообщить, возвращена ли служба. Помните, что данные, подобные тем, которые не могут быть ценными для вас, теперь могут стать ценными позже!
Последнее редактирование (возможно):
В комментарии я предложил вам попробовать try/catch внутри функции2. Просто подумал, что я уточню. Функция2 будет выглядеть так:
public Something? function2()
{
try
{
//all of your function goes here
return anActualObjectOfTypeSomething;
}
catch(Exception ex)
{
//logging goes here
return null;
}
}
Таким образом, поскольку вы используете возвращаемый null тип возвращаемого значения, это не повредит вам.
Ответ 2
Почему вы не можете использовать блок finally?
Как
try {
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY block
} finally {
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
ИЗМЕНИТЬ после изменения вопроса:
Вы можете сделать:
int? returnFromFunction2 = null;
try {
returnFromFunction2 = function2();
return returnFromFunction2.value;
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY block
} finally {
if (returnFromFunction2.HasValue) { // do something with value }
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
Ответ 3
Или вы можете инкапсулировать логику цикла в try catch, например.
for(int i = function2(); i < 100 /*where 100 is the end or another function call to get the end*/; i = function2()){
try{
//ToDo
}
catch { continue; }
}
Или...
try{
for(int i = function2(); ; ;) {
try { i = function2(); return; }
finally { /*decide to break or not :P*/continue; } }
} catch { /*failed on first try*/ } finally{ /*afterwardz*/ }
Ответ 4
просто сделайте это
try
{
//some code
try
{
int idNumber = function2();
}
finally
{
do stuff here....
}
}
catch(Exception e)
{//... perhaps something here}
Для всех целей и задач блок finally всегда будет выполняться. Теперь есть несколько исключений, где это фактически не выполняется: задача убивает программу, и есть быстрое исключение безопасности, которое мгновенно уничтожает приложение. Кроме этого, исключение будет выбрано в функции 2, блок finally выполнит необходимый код и затем поймает исключение во внешнем блоке catch.
Ответ 5
Вы хотите, чтобы вы выполняли код в функции1 независимо от того, выбрала ли функция2 исключение или нет? Вы посмотрели на окончательный блок? http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
Ответ 6
В вашей второй функции удалите переменную e в блоке catch, затем добавьте throw.
Это перенесет генерируемое исключение в конечную функцию и выведет ее.
Это очень часто, когда вы не хотите, чтобы ваш код бизнес-логики генерировал исключение, но ваш интерфейс.