首页 > 解决方案 > C# 并行 - 重复迭代

问题描述

我面临一个奇怪的问题,即迭代中的文件被调用两次。

Parallel.ForEach(context.files.Where(x => x.in_queue == true && x.Uploaded == false), new ParallelOptions { MaxDegreeOfParallelism = 5 }, (fl, state) =>
                {
                    //File upload code
                        fl.in_queue = false;
                        fl.Uploaded = true;
                        log.Debug(string.Format("{0} uploaded", fl.FileName));
                });

我在日志中多次看到相同的文件,但上下文不包含任何重复的条目。

标签: c#.net

解决方案


使用纯代码无法重现显示问题的 NUnit 测试。

就像@RBarryYoung 指出的那样,并发问题很可能是问题所在。

public class CustomFile
{
    public bool in_queue { get; set; }
    public bool Uploaded { get; set; }
    public string FileName { get; set; }
}

[Test]
public void ParallelTest()
{
    var files = Enumerable.Range(1, 10000)
        .Select(it =>
            new CustomFile {in_queue = true, Uploaded = false, FileName = $"{it}_my_file.txt"}
        );

    var usedFileNames = new ConcurrentBag<string>();

    Parallel.ForEach(files
            .Where(x => x.in_queue == true && x.Uploaded == false),
        new ParallelOptions {MaxDegreeOfParallelism = 5}, (fl) =>
        {
            fl.in_queue = false;
            fl.Uploaded = true;
            usedFileNames.Add(fl.FileName);
        });

    Assert.IsFalse(usedFileNames.GroupBy(x => x).Any(x => x.Count() > 1));
}

推荐阅读