并行执行问题

Parallel execution issue

我需要一些有关并行任务执行的知识。

我创建了一个小fiddle:

https://dotnetfiddle.net/JO2a4m

我想做的是将几个帐户分批处理到另一种方法并为每个批次创建一个工作单元(任务)但是当我执行任务时,它只执行添加的最后一个任务.这是我正在努力解决的问题。

代码:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        var accounts = GenerateAccount();
        var accountsProcess = new List<Account>();
        var taskList = new List<Task>();
        var batch = 4;
        var count = 0;
        foreach (var account in accounts)
        {
            if (count == batch)
            {
                taskList.Add(new Task(() => ProcessAccount(accountsProcess)));
                count = 0;
                accountsProcess.Clear();
            }

            count++;
            accountsProcess.Add(account);
        }

        Parallel.ForEach(taskList, t =>
        {
            t.Start();
        }

        );
        Task.WaitAll(taskList.ToArray());
        if (accountsProcess.Count > 0)
            ProcessAccount(accountsProcess);
    }

    public static List<Account> GenerateAccount()
    {
        var accounts = new List<Account>();
        var first = "First";
        var second = "Second";
        for (int i = 0; i <= 1000; i++)
        {
            var account = new Account();
            account.first = first + i;
            account.second = second + i;
            accounts.Add(account);
        }

        return accounts;
    }

    public static void ProcessAccount(List<Account> accounts)
    {
        Console.WriteLine(accounts.Count);
        foreach (var account in accounts)
        {
            Console.WriteLine(account.first + account.second);
        }
    }
}

public class Account
{
    public string first;
    public string second;
}
foreach (var account in accounts)
{
    if (count == batch)
    {
        taskList.Add(new Task(() => ProcessAccount(accountsProcess)));
        count = 0;
        accountsProcess.Clear();
    }

    count++;
    accountsProcess.Add(account);
}

问题是所有 Task 共享同一个 List<Account> 对象。

我建议将代码更改为:

foreach (var account in accounts)
{
    if (count == batch)
    {
        var bob = accountsProcess;
        taskList.Add(new Task(() => ProcessAccount(bob)));
        count = 0;
        accountsProcess = new List<Account>();
    }

    count++;
    accountsProcess.Add(account);
}

通过使用 bob 并将新的 List 分配给 accountsProcess,我们确保每个 Task 都有自己的 List - 而不是共享一个 List.

此外,考虑使用 MoreLINQBatch 而不是自己滚动。