I'm using WMI for querying devices. I need to update UI when new device is inserted or removed (in order to keep list of devices up to date).
private void LoadDevices()
{
using (ManagementClass devices = new ManagementClass("Win32_Diskdrive"))
{
foreach (ManagementObject mgmtObject in devices.GetInstances())
{
foreach (ManagementObject partitionObject in mgmtObject.GetRelated("Win32_DiskPartition"))
{
foreach (ManagementBaseObject diskObject in partitionObject.GetRelated("Win32_LogicalDisk"))
{
trvDevices.Nodes.Add( ... );
}
}
}
}
}
protected override void WndProc(ref Message m)
{
const int WM_DEVICECHANGE = 0x0219;
const int DBT_DEVICEARRIVAL = 0x8000;
const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
switch (m.Msg)
{
// Handle device change events sent to the window
case WM_DEVICECHANGE:
// Check whether this is device insertion or removal event
if (
(int)m.WParam == DBT_DEVICEARRIVAL ||
(int)m.WParam == DBT_DEVICEREMOVECOMPLETE)
{
LoadDevices();
}
break;
}
// Call base window message handler
base.WndProc(ref m);
}
This code throws exception with the following text
The application called an interface that was marshalled for a different thread.
I put
MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
in the beginning of LoadDevices method and I see that it is always called from the same thread (1). Could you please explain what is going on here and how to get rid of this error?
Finally I solved it using new thread.
I split this method, so now I have GetDiskDevices()
and LoadDevices(List<Device>)
methods and I have InvokeLoadDevices()
method.
private void InvokeLoadDevices()
{
// Get list of physical and logical devices
List<PhysicalDevice> devices = GetDiskDevices();
// Check if calling this method is not thread safe and calling Invoke is required
if (trvDevices.InvokeRequired)
{
trvDevices.Invoke((MethodInvoker)(() => LoadDevices(devices)));
}
else
{
LoadDevices(devices);
}
}
When I get either of DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE messages I call
ThreadPool.QueueUserWorkItem(s => InvokeLoadDevices());
Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With