using System; using System.Collections.Generic; namespace SabreTools.Collections.Extensions { public static class EnumerableExtensions { /// /// Wrap iterating through an enumerable with an action /// /// /// .NET Frameworks 2.0 and 3.5 process in series. /// .NET Frameworks 4.0 onward process in parallel. /// public static void IterateWithAction(this IEnumerable source, Action action) { #if NET20 || NET35 foreach (var item in source) { action(item); } #else System.Threading.Tasks.Parallel.ForEach(source, action); #endif } /// /// Safely iterate through an enumerable, skipping any errors /// public static IEnumerable SafeEnumerate(this IEnumerable enumerable) { // Get the enumerator for the enumerable IEnumerator enumerator; try { enumerator = enumerable.GetEnumerator(); } catch { yield break; } // Iterate through and absorb any errors while (true) { // Attempt to move to the next item bool moved; try { moved = enumerator.MoveNext(); } catch (InvalidOperationException) { // Specific case for collections that were modified yield break; } catch (System.IO.IOException ex) when (ex.Message.Contains("The file or directory is corrupted and unreadable.")) { // Specific case we can't circumvent yield break; } catch { continue; } // If the end of the enumeration is reached if (!moved) yield break; // Return the next value from the enumeration yield return enumerator.Current; } } } }