powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / WPF(Window) + WMI (ManagementEventWatcher) = VS2008 Error
2 сообщений из 2, страница 1 из 1
WPF(Window) + WMI (ManagementEventWatcher) = VS2008 Error
    #35141567
Фотография Roman S. Golubin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть класс DirectoryCollection на базе ObservableCollection<T>, в WPF проект подключен как источник данных:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<Window x:Class="project1.UI.Explorer"
    xmlns:common="clr-namespace:project1.common;assembly=project1.common"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="550">
  <Window.Resources>

    <common:DirectoryCollection x:Key="DataSource"/>
    
  </Window.Resources>
  
  <Grid>
    
    <ListView x:Name="catalog" ItemsSource="{StaticResource DataSource}"/>

  </Grid>
</Window>
В классе DirectoryCollection для, собственно, построения коллекции, используется WMI-watcher:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
using System;
using System.Management;
using System.Threading;
using System.Collections.ObjectModel;
using System.Windows.Threading;

namespace project1.common
{
  public class DirectoryCollection : Directory, IDisposable
  {

    public DirectoryCollection()
    {
      InitializeWatcher();
    }

    private void InitializeWatcher()
    {
      WqlEventQuery wqlquery = new WqlEventQuery(watcherquery);
      _watcher = new ManagementEventWatcher(wqlquery);
      _watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
      _watcher.Start();
    }

    private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
    {
      ManagementBaseObject wmiDevice = (ManagementBaseObject)e.NewEvent["TargetInstance"];
      string driveName = (string)wmiDevice["DeviceID"];
      if (wmiDevice["Size"] == null)
      {
        Directory x = null;
        foreach (Directory directory in this)
          if (directory.Path.Substring(0, 2) == driveName)
          {
            x = directory;
            break;
          }
        Remove(x);
      }
      else
      {
        Add(new Directory(driveName));
      }
    }

    #region IDisposable Members

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposed) return;
      disposed = true;

      if (disposing)
      {
        this.Clear();
        _watcher.EventArrived -= new EventArrivedEventHandler(watcher_EventArrived);
        _watcher.Stop();
      }
    }

    ~DirectoryCollection()
    {
      Dispose(false);
    }

    private bool disposed = false;

    #endregion

    private ManagementEventWatcher _watcher;

    private static readonly string watcherquery = @"select * from __InstanceOperationEvent within 0.5 where Targetinstance ISA 'Win32_LogicalDisk' and Targetinstance.DriveType <> 3 and Targetinstance.DeviceID <> 'A:'";
    private static readonly string logicaldisksquery = "select * from Win32_LogicalDisk where DriveType <> 3 and DeviceID <> 'A:' and Size > 0";

  }
}

Все работает отлично, но при выходе из режима отладки, VS падает с ошибкой "COM object that has been separated from its underlying RCW cannot be used." Попробовал прикрутить интерфейс IDisposable, что бы правильно остановить watcher, но UI, похоже, Dispose не вызывает.

Может кто с таким сталкивался? Поделитесь вариантом решения, если есть!
...
Рейтинг: 0 / 0
WPF(Window) + WMI (ManagementEventWatcher) = VS2008 Error
    #35178799
Фотография Roman S. Golubin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разобрался. Проблема в том, что поток, в котором выполняется ManagementEventWatcher, не должен завершаться в момент, когда он производит чтение. Поэтому пришлось сделать так:
1. Отказаться от использования _watcher.EventArrived
2. Вынести работу с ManagementEventWatcher в отдельный поток.
3. Перед использованием _watcher.WaitForNextEvent устанавливаю Thread.IsBackground = false
4. После использования _watcher.WaitForNextEvent устанавливаю Thread.IsBackground = true и Thread.Sleep(200), что бы приложение при завершении могло закрыть поток.

Глюки с выпадением ManagementEventWatcher в ошибку при выходе из приложения исчезли.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / WPF(Window) + WMI (ManagementEventWatcher) = VS2008 Error
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]