简体   繁体   English

Parallel.ForEach的第一个循环

[英]First loop of a Parallel.ForEach

I would like to run some code inside the first loop of a Parallel.ForEach. 我想在Parallel.ForEach的第一个循环内运行一些代码。 Only in the first loop whichever it is. 仅在第一个循环中为准。 The reason is to write some diagnostic data to disk that is produced by the code inside the loop. 原因是将一些诊断数据写入由循环内的代码生成的磁盘。 After the first loop data will be only kept in the memory and aggregated later. 在第一个循环之后,数据将仅保留在内存中,并在以后聚合。 Would this work? 这行得通吗?

bool firstLoop = true;
Parallel.ForEach(someList, 
    p=>
    {
        // do something here

        if (firstLoop)
        {
            firstLoop = false;

            // do something here for the first loop
        }
    });

As mentioned in my comment, this will not be at all guaranteed to work. 正如我在评论中提到的那样,这完全不能保证有效。 One option would be to create a lock and only evaluate and update firstLoop inside the lock. 一种选择是创建一个锁,并且仅评估和更新firstLoop内的firstLoop However, this would cause you to lose a some of your parallelism and would suggest that you look for a better approach, unless you do not have pressing needs around the time that it takes to complete the operation. 但是,这将导致您失去一些并行性,并建议您寻找一种更好的方法,除非您在完成该操作所需的时间中没有紧迫的需求。

Keep in mind that this does not guarantee that firstLoop will be evaluated on the first item in your list, only that it will only be evaluated to true once. 请记住,这并不保证firstLoop将在列表中的第一项上求值,而仅保证它一次只能为true。

var someList = new List<string>();
var obj = new object();

for (int i = 0; i < 1000; i++)
{
    someList.Add(i.ToString());
}

bool firstLoop = true;
var rand = new Random(Guid.NewGuid().GetHashCode());
Parallel.ForEach(someList,
    p =>
    {
        // do something here
        var next = rand.Next(1, 100);
        Thread.Sleep(next);
        lock (obj)
        {
            if (firstLoop)
            {
                firstLoop = false;
                firstLoop.Dump();
                // do something here for the first loop
            }
        }
    });

If you need something to happen on the first item, and the rest of the iterations don't rely on what's being done, you can use the following to see if you're processing the first item 如果您需要在第一项上进行某些操作,而其余的迭代不依赖于正在执行的操作,则可以使用以下内容查看是否正在处理第一项

if (p==items.First())
{
    //Do something
}

If you need to do something once that the rest of the loops will rely on then you can use a lock as suggested by David or you can do what you need before the Parallel.ForEach 如果您需要执行其余循环将依赖的操作,则可以使用David建议的锁,也可以在Parallel.ForEach之前执行所需的操作。

So you could do 所以你可以做

//Do stuff using someList(0)

Parallel.ForEach(someList.Skip(1), p=>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM