Ожидание задачи для L oop C# - PullRequest
0 голосов
/ 26 мая 2020

Я читаю файл и хочу обработать 10 строк за раз.

Это работает, только если я обрабатываю <10 строк. Для l oop просто продолжается и не дожидается завершения первых 10 задач. </p>

Пожалуйста, сообщите.

Ниже мой код:

private void btnStart_Click(object sender, EventArgs e)
{
  int lctr = 0;
  var tasks = new List<Task>();
  foreach (string s in lines)
  {
    if (string.IsNullOrWhiteSpace(s) || string.IsNullOrEmpty(s))
      continue;

    lctr++;
    tasks = new List<Task>();
    if (lctr < 11)
    {
      Console.WriteLine(lctr + " - " + s);
      tasks.Add(Task.Factory.StartNew(() => processThis(s)));
    }
    else
    {                        
    Console.WriteLine("Waiting ...");
    Task.WaitAll(tasks.ToArray());
    }
  }
  if (tasks.Count > 0)
    Task.WaitAll(tasks.ToArray());        
 }

1 Ответ

1 голос
/ 26 мая 2020

Когда вы говорите «Пожалуйста, посоветуйте», это дает мне широкие возможности попытаться помочь. Вот мои предложения, и я надеюсь, вы найдете их «полезными»:

Q: «Я читаю файл и хочу обработать 10 строк за раз».

A: Перед созданием любые задачи, поместите свой тестовый список в группы по 10 строк (и последнюю группу, которая может быть неполной, если, скажем, список состоит из 25 строк).

Вот способ выполнить первую часть:

    // Short-running method that queues up strings in batches of 10 or less
    private static Queue<List<string>> enqueueBatchesOf10orLess(List<string> testData)
    {
        Queue<List<string>> batchesOfUpTo10 = new Queue<List<string>>();
        List<string> singleBatchOfUpTo10 = new List<string>(); ;
        for (int count = 0; count < testData.Count; count++)
        {
            if ((count % 10) == 0) 
            {
                if(count != 0)  // Skip the very first time
                {
                    batchesOfUpTo10.Enqueue(singleBatchOfUpTo10);
                    singleBatchOfUpTo10 = new List<string>();
                }
            }
            singleBatchOfUpTo10.Add(testData[count]);
        }
        // Leftover batch of less-than-10
        if(singleBatchOfUpTo10.Count != 0)
        {
            batchesOfUpTo10.Enqueue(singleBatchOfUpTo10);
        }
        return batchesOfUpTo10;
    }

Затем, похоже, вы хотите обрабатывать эти пакеты одновременно (подразумевая, что может быть некоторое время обработки, которое оправдывает это). Вот как вы передаете свои «партии из 10 или меньше» и получаете взамен задание.

    private static Task processBatch(Queue<List<string>> batches)
    {            
        return Task.Run(() => // Return task that processes batch of 10 or less
        {
            var batch = batches.Dequeue();
            foreach (var singleString in batch)
            {
                processThis(singleString);
            }
        });
    }

... где ...

    private static void processThis(string s)
    {
        Task.Delay(100).Wait(); // Simulate long-running string processing
        Console.WriteLine(s);
    }

Чтобы проверить это:

    static void Main(string[] args)
    {
        // Make some test data
        List<string> testData = new List<string>();
        for (int i = 0; i < 25; i++) testData.Add((i + 1).ToString());

        Queue<List<string>> batchesOf10OrLess = enqueueBatchesOf10orLess(testData);

        List<Task> tasks = new List<Task>();
        for (int i = 0; i < batchesOf10OrLess.Count; i++)
        {
            // Pass in the queue of batches and get a Task in return.
            tasks.Add(processBatch(batchesOf10OrLess));
        }
        Console.WriteLine("The test data is NOT in order.");
        Console.WriteLine("This is proof the tasks are running concurrently");
        Task.WaitAll(tasks.ToArray());

        // Pause
        Console.ReadKey();
    }

Вот что мы получаем:

The test data is NOT in order.
This is proof the tasks are running concurrently
1
21
11
2
12
22
3
23
13
4
14
24
5
25
15
6
16
7
17
8
18
19
9
10
20

Если вам нравится скачайте этот образец с GitHub.

...