2012-08-31 8 views
6

के लिए marshalled किया गया था मैं क्वेरी उपकरणों के लिए WMI का उपयोग कर रहा हूँ। जब नई डिवाइस डाली जाती है या हटा दी जाती है (डिवाइस को अद्यतित रखने की सूची में) को UI को अपडेट करने की आवश्यकता होती है।एप्लिकेशन को एक इंटरफ़ेस कहा जाता है जिसे एक अलग थ्रेड

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); 
} 

इस कोड को निम्न पाठ

The application called an interface that was marshalled for a different thread.

मैं LoadDevices विधि की शुरुआत में

MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString()); 

डाल के साथ अपवाद फेंकता है और मुझे लगता है कि यह हमेशा एक ही से कहा जाता है धागा (1)। क्या आप कृपया बता सकते हैं कि यहां क्या हो रहा है और इस त्रुटि से कैसे छुटकारा पाएं?

उत्तर

2

अंत में मैंने इसे नए धागे का उपयोग करके हल किया। मैंने इस विधि को विभाजित किया है, इसलिए अब मेरे पास GetDiskDevices() और LoadDevices(List<Device>) विधियां हैं और मेरे पास InvokeLoadDevices() विधि है।

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); 
    } 
} 

जब मैं DBT_DEVICEARRIVAL या DBT_DEVICEREMOVECOMPLETE संदेशों के या तो मिलता है मैं फोन

ThreadPool.QueueUserWorkItem(s => InvokeLoadDevices()); 

धन्यवाद।

0

UWP लिए W10 आप इस्तेमाल कर सकते हैं पर:

public async SomeMethod() 
{ 
    await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.High,() => 
     { 
      // Your code here... 
     }); 
} 
संबंधित मुद्दे