C# 列表<;T>;获取正在执行的区块编号

C# 列表<;T>;获取正在执行的区块编号,c#,linq,C#,Linq,我正在将一个列表分成若干块,并按如下方式进行处理: foreach (var partialist in breaklistinchunks(chunksize)) { try { do something } catch { print error } } public static class IEnumerableExtensions { public static IEnumerable<List<T>>

我正在将一个列表分成若干块,并按如下方式进行处理:

foreach (var partialist in breaklistinchunks(chunksize))
{
  try
   {
       do something
  }
catch
{
print error
}

}



public static class IEnumerableExtensions
    {
        public static IEnumerable<List<T>> BreakListinChunks<T>(this IEnumerable<T> sourceList, int chunkSize)
        {
            List<T> chunkReturn = new List<T>(chunkSize);
            foreach (var item in sourceList)
            {
                chunkReturn.Add(item);
                if (chunkReturn.Count == chunkSize)
                {
                    yield return chunkReturn;
                    chunkReturn = new List<T>(chunkSize);
                }
            }
            if (chunkReturn.Any())
            {
                yield return chunkReturn;
            }
        }
    }
foreach(breaklistinchunks中的var partialist(chunksize))
{
尝试
{
做点什么
}
接住
{
打印错误
}
}
公共静态类IEnumerableExtensions
{
公共静态IEnumerable BreakListinChunks(此IEnumerable sourceList,int chunkSize)
{
List chunkReturn=新列表(chunkSize);
foreach(sourceList中的var项)
{
chunkReturn.Add(项目);
if(chunkReturn.Count==chunkSize)
{
收益率;收益率;
chunkReturn=新列表(chunkSize);
}
}
if(chunkReturn.Any())
{
收益率;收益率;
}
}
}
如果出现错误,我希望再次运行块。是否有可能找到接收到错误的特定块号并再次运行?
批处理必须按顺序执行。因此,如果批处理#2生成错误,那么我需要能够再次运行2,如果它再次失败。我只需要永远退出循环。

一种可能是使用for循环而不是foreach循环,并使用计数器作为确定错误发生位置的手段。然后,您可以从中断处继续。

一种可能是使用for循环而不是foreach循环,并使用计数器作为确定错误发生位置的手段。然后,您可以从停止的地方继续。

List failedChunks=new List();
List<Chunk> failedChunks = new List<Chunk>();
foreach (var partialist in breaklistinchunks(chunksize))
{
    try
    {
        //do something
    }
    catch
    {
        //print error
        failedChunks.Add(partiallist);
    }

}

// attempt to re-process failed chunks here
foreach(breaklistinchunks中的var partialist(chunksize)) { 尝试 { //做点什么 } 接住 { //打印错误 failedChunks.Add(partiallist); } } //尝试在此处重新处理失败的块
列出失败的区块=新建列表();
foreach(breaklistinchunks中的var partialist(chunksize))
{
尝试
{
//做点什么
}
接住
{
//打印错误
failedChunks.Add(partiallist);
}
}
//尝试在此处重新处理失败的块

如果您不介意从可枚举切换到队列,我为您提供了一个可能的解决方案,这种方式适合给定的需求

void Main()
{
    var list = new Queue<int>();
    list.Enqueue(1);
    list.Enqueue(2);
    list.Enqueue(3);
    list.Enqueue(4);
    list.Enqueue(5);

    var random = new Random();

    int chunksize = 2;
    foreach (var chunk in list.BreakListinChunks(chunksize))
    {
        foreach (var item in chunk)
        {   
            try
            {           
                if(random.Next(0, 3) == 0) // 1 in 3 chance of error
                    throw new Exception(item + " is a problem");
                else
                    Console.WriteLine (item + " is OK");
            }
            catch (Exception ex)
            {
                Console.WriteLine (ex.Message);
                list.Enqueue(item);
            }
        }
    }
}

public static class IEnumerableExtensions
{   
    public static IEnumerable<List<T>> BreakListinChunks<T>(this Queue<T> sourceList, int chunkSize)
    {
        List<T> chunkReturn = new List<T>(chunkSize);
        while(sourceList.Count > 0)
        {
            chunkReturn.Add(sourceList.Dequeue());
            if (chunkReturn.Count == chunkSize || sourceList.Count == 0)
            {
                yield return chunkReturn;
                chunkReturn = new List<T>(chunkSize);
            }       
        }
    }
}

如果您不介意从可枚举切换到队列,我为您提供了一个可能的解决方案,这种方式适合给定的需求

void Main()
{
    var list = new Queue<int>();
    list.Enqueue(1);
    list.Enqueue(2);
    list.Enqueue(3);
    list.Enqueue(4);
    list.Enqueue(5);

    var random = new Random();

    int chunksize = 2;
    foreach (var chunk in list.BreakListinChunks(chunksize))
    {
        foreach (var item in chunk)
        {   
            try
            {           
                if(random.Next(0, 3) == 0) // 1 in 3 chance of error
                    throw new Exception(item + " is a problem");
                else
                    Console.WriteLine (item + " is OK");
            }
            catch (Exception ex)
            {
                Console.WriteLine (ex.Message);
                list.Enqueue(item);
            }
        }
    }
}

public static class IEnumerableExtensions
{   
    public static IEnumerable<List<T>> BreakListinChunks<T>(this Queue<T> sourceList, int chunkSize)
    {
        List<T> chunkReturn = new List<T>(chunkSize);
        while(sourceList.Count > 0)
        {
            chunkReturn.Add(sourceList.Dequeue());
            if (chunkReturn.Count == chunkSize || sourceList.Count == 0)
            {
                yield return chunkReturn;
                chunkReturn = new List<T>(chunkSize);
            }       
        }
    }
}

我提出这个答案是基于对的


批处理必须按顺序执行。因此,如果2出现问题,那么如果2再次失败,我需要能够再次运行2。我只需要永远摆脱这个循环

foreach(breaklistinchunks中的var partialist(chunksize))
{
int=0;
布尔成功=假;
做
{
尝试
{
//行动起来
success=true;//应位于“catch”之前的最后一行
}
接住
{
失败+=1;
//在再次运行之前,请对错误进行处理
}
}而(!success&&fails<2);
//如果未成功且失败为2,则退出迭代
如果(!success&&fails>=2)
打破
}

我根据to提出这个答案


批处理必须按顺序执行。因此,如果2出现问题,那么如果2再次失败,我需要能够再次运行2。我只需要永远摆脱这个循环

foreach(breaklistinchunks中的var partialist(chunksize))
{
int=0;
布尔成功=假;
做
{
尝试
{
//行动起来
success=true;//应位于“catch”之前的最后一行
}
接住
{
失败+=1;
//在再次运行之前,请对错误进行处理
}
}而(!success&&fails<2);
//如果未成功且失败为2,则退出迭代
如果(!success&&fails>=2)
打破
}

您可以使用
break
在块失败两次后立即退出循环:

foreach (var partialList in breaklistinchunks(chunksize))
{
    if(!TryOperation(partialList) && !TryOperation(partialList))
    {
        break;
    }
}

private bool TryOperation<T>(List<T> list)
{
    try
    {
        // do something
    }
    catch
    {
        // print error
        return false;
    }
    return true;
}

您可以使用
break
在块失败两次时退出循环:

foreach (var partialList in breaklistinchunks(chunksize))
{
    if(!TryOperation(partialList) && !TryOperation(partialList))
    {
        break;
    }
}

private bool TryOperation<T>(List<T> list)
{
    try
    {
        // do something
    }
    catch
    {
        // print error
        return false;
    }
    return true;
}

breaklistinchunks
是什么样子的?我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。简短的回答是,如果不使用外部变量,您就无法使用foreach。关于这个问题,这里有一条长长的线索:@ChrisShain我已经更新了我的问题。
breaklistinchunks
是什么样子的?我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。简短的回答是,如果不使用外部变量,您就无法使用foreach。关于这个问题,这里有一条长长的线索:@ChrisShain我已经更新了我的问题。你是说类似这样的问题吗?例如(inti=0;iYes,尽管你的返回类型必须可以通过索引访问(例如列表)。你的意思是什么?例如(inti=0;iYes,尽管你的返回类型必须可以通过索引访问(例如列表)。根据他的帖子,我认为“Chunk”应该是List。另外,如果你明确希望foreach循环中的索引,你可以做breaklistinockuns(size)。根据他的帖子选择((chunk,index)=>new{chunk,index}),我认为“chunk”应该是List。另外,如果你明确希望foreach循环中的索引,你可以做breaklistinockuns(size)。选择((chunk,index)=>new{chunk,index})批处理必须按顺序执行。因此,如果2出现问题,那么如果2再次失败,我需要能够再次运行2。我只需要永远脱离循环。我不确定这是否符合生成列表的想法,这是我所知道的以块处理的唯一方法……这对我来说很有趣,因为我似乎总是在编写如果我有任何想法,我会让你知道批处理必须按顺序执行。所以如果2是一个问题,那么我需要能够再次运行2,如果它再次失败。我只需要退出循环
breaklistinchunks(chunksize).TakeWhile(x => TryOperation(x) || TryOperation(x));