1

私はリストをチャンクに分割し、以下のように処理しています:

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

エラーが発生した場合は、チャンクを再度実行したいと思います。エラーを受け取った特定のチャンク番号を見つけて、それを再度実行することは可能ですか?バッチは順番に実行する必要があります。したがって、batch#2でエ​​ラーが発生した場合、再度失敗した場合は2を再度実行できるようにする必要があります。私はただループから抜け出す必要があります。

4

5 に答える 5

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
于 2012-10-25T01:17:17.190 に答える
2

アーロンの回答に対するあなたのコメントに基づいて、この回答を提案します。

バッチは順番に実行する必要があります。したがって、2が問題である場合、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;
}
于 2012-10-25T02:41:50.170 に答える
1

EnumerableからQueueに切り替えてもかまわない場合は、可能な解決策を作成しました。これは、要件に応じてどのような種類に適合しますか...

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
于 2012-10-25T01:37:05.660 に答える
0

1つの可能性は、foreachループの代わりにforループを使用し、エラーが発生した場所を判別する手段としてカウンターを使用することです。その後、中断したところから続行できます。

于 2012-10-25T01:12:12.107 に答える
0

breakチャンクが2回失敗するとすぐに、ループを終了するために使用できます。

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));
于 2012-10-25T02:45:42.953 に答える