对列表中的所有项目不执行操作的C#Parallel.Foreach

    public static void RemoveAllNetworkPrinters()
    {
        ManagementScope oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
        oManagementScope.Connect();

        SelectQuery oSelectQuery = new SelectQuery();
        oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer WHERE ServerName IS NOT NULL";

        using (ManagementObjectSearcher oObjectSearcher = new ManagementObjectSearcher(oManagementScope, oSelectQuery))
        {
            using (ManagementObjectCollection oObjectCollection = oObjectSearcher.Get())
            {
                if (oObjectCollection.Count != 0)
                {
                    foreach (ManagementObject oItem in oObjectCollection)
                    {
                        oItem.Delete();

                    }
                }
            }
        }
    }

    public static void RemoveAllNetworkPrintersParallel()
    {
        ManagementScope oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
        oManagementScope.Connect();

        SelectQuery oSelectQuery = new SelectQuery();
        oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer WHERE ServerName IS NOT NULL";

        using (ManagementObjectSearcher oObjectSearcher = new ManagementObjectSearcher(oManagementScope, oSelectQuery))
        {
            using (ManagementObjectCollection oObjectCollection = oObjectSearcher.Get())
            {
                if (oObjectCollection.Count != 0)
                {
                    Parallel.ForEach(oObjectCollection.OfType<ManagementObject>().ToList(), oItem =>
                    {
                        oItem.Delete();
                    });
                }
            }
        }
    }

我有一个关于c#中的Parallel.Foreach的问题。 我一直在测试,并看到一些奇怪的例子,我正在提供用于测试目的。 当我执行此功能的非并行版本时,它工作正常,但是当我在1-2个项目之间的任何位置执行并行版本时,将无法在列表中进行循环。 我已阅读msdn文档,但必须在这里丢失一些东西。 我知道你不能保证订单商品将被处理,但认为它可以保证所有商品都将在列表中处理? 任何帮助理解或我做错了什么将不胜感激。 谢谢


正如在注释中所讨论的, ManagementObject.Delete()不是线程安全的操作,所以你不应该使用它从不同的线程MSDN

此类型的任何公共静态(Visual Basic中的Shared)成员都是线程安全的。 任何实例成员不保证是线程安全的。

但是如果你真的需要这样做,而你想在那里使用lock ,那么可以这样做smthg

var lockObject = new Object();

Parallel.ForEach(/*.....*/, item =>
{
    lock (lockObject)
    {
        // do your magic here
    }
});

但是正如我所说的,使用这些代码是没有意义的,因为它会比通常的foreach慢

所以,我的建议 - 只用foreach。

链接地址: http://www.djcxy.com/p/50159.html

上一篇: C# Parallel.Foreach that is not peforming action on all items in list

下一篇: C# parallel programming modifying xDocument