2014-10-27 5 views
1

Я в настоящее время загрузки изображений по-разному, как это:попытки поймать внутри пункта поймать

try { 
    // way 1 
} 
catch 
{ // way 1 didn't work 
    try { 
     // way 2 
    } 
    catch 
    { 
     // etc. 
    } 
} 

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

+1

«Почему это не работает?» И обрабатывать это более эффективная практика проектирования, а не позволяющая чему-то выкинуть ошибку и надеяться, что вы покроете ее вложенными уловами (особенно для чего-то вроде этого). Что происходит, когда вы бросаете ошибки, пытаясь загрузить изображение? – alykins

+0

вы можете иметь несколько инструкций catch. Я бы также посоветовал ** предотвратить ** попытку неудачи вместо ** вылечить ** проблему в первую очередь –

+0

Используют ли библиотеки, которые вы используете, чтобы проверить, действительно ли данные действительны? В любом случае - я бы, вероятно, извлек каждую «попытку» в отдельный метод. Например: TryGetJPG() - который возвращает поток (или что бы вы хотели) при успехе, null при ошибке. – Rob

ответ

9

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

public static void AttemptAll(params Action[] actions) 
{ 
    var exceptions = new List<Exception>(); 
    foreach (var action in actions) 
    { 
     try 
     { 
      action(); 
      return; 
     } 
     catch (Exception e) 
     { 
      exceptions.Add(e); 
     } 
    } 
    throw new AggregateException(exceptions); 
} 

Это позволяет написать:

AttemptAll(Attempt1, Attempt2, Attempt3); 

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

public static T AttemptAll<T>(params Func<T>[] actions) 
{ 
    var exceptions = new List<Exception>(); 
    foreach (var action in actions) 
    { 
     try 
     { 
      return action(); 
     } 
     catch (Exception e) 
     { 
      exceptions.Add(e); 
     } 
    } 
    throw new AggregateException(exceptions); 
} 
+0

Я вижу, что было бы чище, спасибо! – Subject009

+0

+1 для агрегирования и исключения исключений, если все действия терпят неудачу. – juharr

+0

Мне очень нравится это решение. Это чисто и понятно. Кроме того, это то, что я искал сейчас. – Bovaz

1

Если предположить, что «различные способы», чтобы загрузить изображение все бросить исключение при неудаче, можно перебирать различные способы, пока не удается. В приведенном ниже примере используется Function<Image>, чтобы показать функцию без параметров, которая возвращает изображение с успехом. В вашем конкретном примере вы, вероятно, также имеете параметры в своей функции.

List<Function<Image>> imageLoaders = LoadTheListSomehow(); 

foreach (var loader in imageLoaders) 
{ 
    try 
    { 
     var image = loader(); 
     break; // We successfully loaded the image 
    } 
    catch (Exception ex) 
    { 
     // Log the exception if desired 
    } 
} 
1

Вложения там не нужны. Я бы изолировал каждый способ загрузки изображения в свой собственный частный метод, а затем назвал эти методы в качестве делегатов в цикле, например:

private static MyImage LoadFirstWay(string name) { 
    return ... 
} 
private static MyImage LoadSecondWay(string name) { 
    return ... 
} 
private static MyImage LoadThirdWay(string name) { 
    return ... 
} 
... 
public MyImage LoadImage(string name) { 
    Func<string,MyImage>[] waysToLoad = new Func<string,MyImage>[] { 
     LoadFirstWay 
    , LoadSecondWay 
    , LoadThirdWay 
    }; 
    foreach (var way in waysToLoad) { 
     try { 
      return way(name); 
     } catch (Exception e) { 
      Console.Error("Warning: loading of '{0}' failed, {1}", name, e.Message); 
     } 
    } 
    return null; 
} 
Смежные вопросы