简体   繁体   English

在foreach条件下抛出异常

[英]Catch exception thrown in foreach condition

I have a foreach loop that breaks during the loop in the condition of the foreach itself. 我有一个foreach循环在foreach本身的情况下在循环中断开。 Is there a way to try catch the item that throws the exception and then continue the loop? 有没有办法try catch抛出异常然后继续循环的项目?

This will run a few times until the exception hits and then end. 这将运行几次,直到异常命中然后结束。

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

This will not run at all because the exception is in the condition of the foreach 这根本不会运行,因为异常是在foreach的条件下

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

I know some of you are going to ask how this is happening so here is this: Exception PrincipalOperationException is being thrown because a Principal (b in my example) cannot be found in GroupPrincipal (bees). 我知道你们中的一些人会问这是怎么回事,所以这就是:异常PrincipalOperationException被抛出,因为在GroupPrincipal (蜜蜂)中找不到Principal (在我的例子中为b)。

Edit: I added the code below. 编辑:我添加了以下代码。 I also figured out that one group member was pointing to a domain that no longer exists. 我还发现一个组成员指向一个不再存在的域。 I easily fixed this by deleting the member but my question still stands. 我通过删除该成员轻松解决了这个问题,但我的问题仍然存在。 How do you handle exceptions that are thrown inside the condition of a foreach? 你如何处理在foreach条件下抛出的异常?

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
}

Almost the same as the answer from @Guillaume, but "I like mine better": 几乎与@Guillaume的答案相同,但“我更喜欢我的”:

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;
            }
        }
    }
}

Maybe you can try to create a method like that: 也许你可以尝试创建一个这样的方法:

    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 this way: 你可以这样使用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM