Throw an exception caused by the foreach clause

I have a foreach that breaks during the loop in the condition of the foreach itself. Is there a way to try catch element that throws an exception and then continue the loop?

This will be executed several times until the exception succeeds and then ends.

 try { foreach(b in bees) { //exception is in this line string += b; } } catch { //error } 

This will not work at all because the exception is in foreach state

 foreach(b in bees) { //exception is in this line try { string += b; } catch { //error } } 

I know that some of you will ask how this happens, like this: PrincipalOperationException is GroupPrincipal because Principal (b in my example) cannot be found in GroupPrincipal (bees).

Edit: I added the code below. I also found out that one member of the group was pointing to a domain that no longer exists. I easily fixed this by deleting the participant, but my question still remains. How do you handle exceptions that are thrown inside the foreach condition?

 PrincipalContext ctx = new PrincipalContext(ContextType.domain); GroupPrincipal gp1 = GroupPrincipal.FindByIdentity(ctx, "gp1"); GroupPrincipal gp2 = GroupPrincipal.FindByIdentity(ctx, "gp2"); var principals = gp1.Members.Union(gp2.Members); foreach(Principal principal in principals) { //error is here //do stuff } 
+8
c # foreach exception try-catch
source share
3 answers

Almost the same as the answer from @Guillaume, but β€œI like mine better”:

 public static class Extensions { public static IEnumerable<T> TryForEach<T>(this IEnumerable<T> sequence, Action<Exception> handler) { if (sequence == null) { throw new ArgumentNullException("sequence"); } if (handler == null) { throw new ArgumentNullException("handler"); } var mover = sequence.GetEnumerator(); bool more; try { more = mover.MoveNext(); } catch (Exception e) { handler(e); yield break; } while (more) { yield return mover.Current; try { more = mover.MoveNext(); } catch (Exception e) { handler(e); yield break; } } } } 
+3
source share

Perhaps you can try to create a method like this:

  public IEnumerable<T> TryForEach<T>(IEnumerable<T> list, Action executeCatch) { if (list == null) { executeCatch(); } IEnumerator<T> enumerator = list.GetEnumerator(); bool success = false; do { try { success = enumerator.MoveNext(); } catch { executeCatch(); success = false; } if (success) { T item = enumerator.Current; yield return item; } } while (success); } 

and you can use it as follows:

  foreach (var bee in TryForEach(bees.GetMembers(), () => { Console.WriteLine("Error!"); })) { } 
+3
source share

I prefer to use an aggregate exception handler. no extensions needed.

.NET Framework 4.6 and 4.5

The AggregateException class did not test the code, but there is logic there.

  try { foreach (var item in items) { try { //something //your own exception (eg.) if (item < 0x3) throw new ArgumentException(String.Format("value is {0:x}. Elements must be greater than 0x3.")); } catch (Exception regularException) { //predefined exceptions (eg.) throw new ArgumentException(regularException.InnerException.ToString()); } } } catch (AggregateException ae) { ae.Handle((inner) => { //handle your aggregate exceptions Debug.WriteLine(inner.Message); }); } 
0
source share

All Articles