I need to perform various queries to different WMI classes, then instead of doing query one by one, to improve the speed of execution I thinked in this:
In C# or else VB.Net, I would like to know whether a single query can be done to retrieve the properties of multiple classes at once.
Random not functional example:
Using wmi As New Management.ManagementObjectSearcher(
"select SerialNumber from Win32_BaseBoard, select Caption from Win32_Process"
)
...
End Using
If yes, which is the proper query syntax?
How about this, using NET 4.5:
Imports System.Management
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Dim wql As String() = {"SELECT SerialNumber FROM Win32_BaseBoard",
"SELECT Name FROM Win32_BIOS",
"SELECT VideoProcessor FROM Win32_VideoController",
"SELECT RegisteredUser FROM Win32_OperatingSystem"}
Dim tasks As New List(Of Task)
For Each q In wql
Dim t As task = Task.Run(Sub()
Dim str = WMI.GetWMIClassProperty(q)
wList.Add(str)
End Sub
)
tasks.Add(t)
Next
Task.WaitAll(tasks.ToArray)
This is the NET 4.0 version:
Dim wmiAction As Action(Of Object) = Sub(s As Object)
Dim str = WMI.GetWMIClassProperty(s.ToString)
wList.Add(str)
End Sub
Dim tasks As New List(Of Task)
For Each q In wql
Dim t As New task(wmiAction, q)
tasks.Add(t)
t.Start()
Next
Task.WaitAll(tasks.ToArray)
WMI.GetWMIClassProperty
just creates a searcher for the query and returns the first property or String.Empty
.
Using a Stopwatch
it takes 72-80ms to run the 4 in succession, 15-20ms to run them as Tasks (NET 4 ver is 2-3ms slower). Almost as fast (18-25ms) is a Parrallel.ForEach
but seems a but less involved and also works with NET 4.0:
Parallel.ForEach(wql, Sub(thisQ)
Dim str = WMI.GetWMIClassProperty(thisQ)
wList.Add(str)
End Sub)
All four methods return the same results in wList
, though in differing orders, so you'd want a way to qualify which results are which. The differences do increase if you query some of the truly slow WMI classes.