首页 新闻 会员 周边 捐助

使用Parallel.ForEach处理时,数据不正确

0
悬赏园豆:5 [已解决问题] 解决于 2024-05-06 17:10

再数据量很大时,在使用Parallel.ForEach循环处理时,主表和字表的分数始终对不上,但是一条一条处理时,就可以对的上。

灬丶的主页 灬丶 | 初学一级 | 园豆:6
提问于:2023-09-08 17:42
< >
分享
最佳答案
0

在使用Parallel.ForEach循环处理大数据集时,可能会遇到数据不正确的问题。这是由于并行处理可能导致数据竞争和并发访问问题。

并行处理会将数据集拆分为多个子集,并同时处理这些子集。在并行处理期间,如果多个线程同时访问和修改共享的数据,就会出现数据不正确的情况。

为了解决这个问题,你可以考虑以下几点:

  1. 使用线程安全的集合:在并行处理期间,使用线程安全的集合来存储和访问数据。例如,可以使用ConcurrentBagConcurrentDictionary等线程安全的集合类。

  2. 避免共享状态:尽量避免在并行处理期间共享状态。如果可能的话,将数据拆分为独立的子集,每个子集由一个线程独立处理。

  3. 使用同步机制:如果必须共享状态,确保对共享数据的访问是同步的。可以使用锁(lock语句)、互斥体(Mutex类)等同步机制来保护共享数据的访问。

  4. 考虑数据依赖性:如果主表和字表之间存在依赖关系,确保在处理主表之前,字表的数据已经完全准备好。可以使用Parallel.ForEachParallelOptions参数中的TaskScheduler属性来控制任务的调度顺序。

  5. 进行数据验证:在并行处理结束后,对结果进行验证,确保数据的正确性。可以使用断言(Debug.Assert)或其他验证机制来检查数据的一致性。

当使用Parallel.ForEach处理并行任务时,可以使用lock语句来保护共享数据的访问。下面是一个示例代码:

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

class Program
{
    static void Main(string[] args)
    {
        List<int> sharedData = new List<int>();
        object lockObject = new object();

        Parallel.ForEach(Enumerable.Range(1, 10), (i) =>
        {
            // 访问共享数据之前加锁
            lock (lockObject)
            {
                sharedData.Add(i);
            }

            // 模拟一些耗时的操作
            Task.Delay(TimeSpan.FromSeconds(1)).Wait();

            // 访问共享数据之前加锁
            lock (lockObject)
            {
                Console.WriteLine($"Thread {Task.CurrentId}: {string.Join(", ", sharedData)}");
            }
        });

        Console.WriteLine($"Final result: {string.Join(", ", sharedData)}");
    }
}

在上面的示例中,我们创建了一个共享的List<int>对象和一个用于同步的lockObject对象。在每个并行任务中,我们使用lock语句来保护对共享数据的访问。这样可以确保每个任务在访问共享数据时是同步的。

请注意,使用lock语句会引入一定的开销,因为每个任务在访问共享数据时都需要获取锁。因此,在使用同步机制时,要确保共享数据的访问频率不会导致性能下降。

另外,如果共享数据的访问逻辑更加复杂,或者需要更高级的同步机制,你还可以考虑使用Monitor类、Mutex类或其他同步机制来保护共享数据的访问。这些同步机制的选择取决于具体的需求和场景。

收获园豆:3
lanedm | 老鸟四级 |园豆:2396 | 2023-09-09 19:54
其他回答(1)
0

使用 Parallel.ForEachAsync

收获园豆:2
JoJo^ | 园豆:204 (菜鸟二级) | 2023-11-01 14:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册