C# Parallel.Foreach that is not peforming action on all items in list
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();
});
}
}
}
}
I have a question in reference to the Parallel.Foreach in c#. I have been testing with and see something odd in example I am providing for testing purposes. When I perform the non parallel version of this function it works fine but when I do a parallel version anywhere between 1-2 items will not process in the list I am cycling through. I have read the msdn documentation but must be missing something here. I know you can't guarantee the order items will be processed but thought it was guaranteed all items would be processed in the list? Any help in understanding or what I am doing wrong would be greatly appreciated. Thanks
As discussed in comments, ManagementObject.Delete()
is not thread safe operation, so you should not use it from different threads MSDN
Any public static ( Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
But if you really need to do this and you want to use lock
there, you can do smthg like this
var lockObject = new Object();
Parallel.ForEach(/*.....*/, item =>
{
lock (lockObject)
{
// do your magic here
}
});
BUT as I said its is not make sense to use this code since it will be slower that ordinal foreach .
So, my recommendation - use just foreach.
链接地址: http://www.djcxy.com/p/50160.html