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