2012-10-25 113 views
1

我打破了列表分割成塊,並如下處理它:列表<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; 
      } 
     } 
    } 

如果有錯誤,我要再次運行該塊。是否有可能找到我們收到錯誤的特定塊編號並再次運行? 批次必須按順序執行。因此,如果批次#2產生錯誤,那麼如果再次失敗,我需要能夠再次運行2。我只是需要擺脫困境。

+1

「breaklistinchunks」是什麼樣的? –

+1

我編輯過你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

+0

簡單的答案是,你不能使用foreach而不使用外部變量。這裏有一個長問題:http://stackoverflow.com/questions/43021/how-do-you-get-the-index-of-the-current-iteration-of-a-foreach-loop – Candide

回答

2

我建議這個答案根據your commentAaron's answer

批次必須按順序執行。所以如果2是一個問題,那麼我需要能夠再次運行2,如果它再次失敗。我只是需要擺脫困境。

foreach (var partialist in breaklistinchunks(chunksize)) 
{ 
    int fails = 0; 
    bool success = false; 

    do 
    { 
     try 
     { 
      // do your action 
      success = true; // should be on the last line before the 'catch' 
     } 
     catch 
     { 
      fails += 1; 
      // do something about error before running again 
     } 
    }while (!success && fails < 2); 

    // exit the iteration if not successful and fails is 2 
    if (!success && fails >= 2) 
     break; 
} 
+0

謝謝這是完美的:) – user1110790

0

一種可能性是使用爲一個循環,而不是foreach循環的,並使用計數器作爲一種手段來確定發生了錯誤的位置。然後你可以從你離開的地方繼續。

+0

你的意思是什麼? 對(INT I = 0; I user1110790

+0

是的,儘管您的返回類型必須可以通過索引訪問(例如,List <>)。 – Inisheer

4
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 
+0

基於他的文章,我認爲「大塊」應該是列表。另外,如果你明確地希望在foreach循環中使用索引,你可以做BreakListIntoChunks(size).Select((chunk,index)=> new {chunk,index}) – ChaseMedallion

1

我做了一個可能的解決方案爲你,如果你不介意從可枚舉切換到隊列中,哪一種給定的要求,千篇一律的...

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

輸出

1 is a problem 
2 is OK 
3 is a problem 
4 is a problem 
5 is a problem 
1 is a problem 
3 is OK 
4 is OK 
5 is OK 
1 is a problem 
1 is OK 
+0

批次必須按順序執行。所以如果2是一個問題,那麼我需要能夠再次運行2,如果它再次失敗。我只是需要擺脫困境。 – user1110790

+0

我不確定這可以適應產生列表的想法,這是我知道以塊處理的唯一方法...這對我很有趣,因爲它似乎總是寫代碼來完成這種類型的事情,所以如果我有任何想法,我會讓你知道 –

0

您可以使用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; 
} 

你甚至可以使環變成一內膽採用LINQ,但它通常是將LINQ與副作用結合在一起的不良做法,並且它不太易讀:

breaklistinchunks(chunksize).TakeWhile(x => TryOperation(x) || TryOperation(x));