2009-12-10 5 views
1

У меня простая форма с двумя кнопками (Пуск и Стоп) и DataGridView. Я пытаюсь заполнить DataGridView результатами запроса WMI, который перечисляет экземпляры Win32_Process и помещает все имена процессов в единственный столбец DataGridView. Код выглядит следующим образом:Приложение зависает после заполнения DataGridView

using System; 
using System.Management; 
using System.Windows.Forms; 

namespace WindowsFormsApplication10 
{ 
    public partial class Form1 : Form 
    { 
     ManagementObjectSearcher Searcher = 
      new ManagementObjectSearcher(); 

     SelectQuery Query = new SelectQuery(); 

     ManagementOperationObserver Observer = 
      new ManagementOperationObserver(); 

     public Form1() 
     { 
      InitializeComponent(); 

      Observer.Completed += 
       new CompletedEventHandler(Observer_Completed); 
      Observer.ObjectReady += 
       new ObjectReadyEventHandler(Observer_ObjectReady); 
      Grid.ColumnCount = 1; 
      Grid.Columns[0].Name = "Name"; 
     } 

     private void Start_Click(object sender, EventArgs e) 
     { 
      Query.QueryString = "Select * From Win32_Process"; 
      Searcher.Query = Query; 

      Searcher.Get(Observer); 
     } 

     private void Observer_Completed 
      (object sender, CompletedEventArgs e) 
     { 
      Grid.Refresh(); 
     } 

     private void Observer_ObjectReady 
      (object sender, ObjectReadyEventArgs e) 
     { 
      string [] row = new string [] 
       {e.NewObject["Name"].ToString()}; 
      Grid.Rows.Add(row); 

      Grid.Refresh(); 
     } 

     private void stop_Click(object sender, EventArgs e) 
     { 
      Observer.Cancel(); 
     } 
    } 
} 

Когда я запускаю код, используя опцию «Начать отладку» он прекрасно работает и заполнит DataGridView. Одна странная вещь (по крайней мере для меня), я заметил, что в Observer_ObjectReady линия Grid.Refresh() никогда не достигается. Когда я запускаю код с «Начать без отладки», DataGridView заполняется, но форма сразу же замораживается. Как я могу справиться с этим? (Извините, если этого недостаточно информации - я готов предоставить больше, если необходимо, но, как вы могли заметить, у меня нет большого опыта работы с C# или Visual Studio).

ответ

0

Вам не следует добавлять строку в свой GridView каждый раз, когда вы получаете новую запись. Вы можете загрузить все свои процессы в коллекцию и связать их с вашим контролем.

Я просто нашел эту ссылку и читает ее исходный код может помочь вам достичь вашей цели: Manage Processes on Remote Machine

+0

Благодарим вас за ответ. Это приложение использует синхронное перечисление, и я также смог заставить его работать таким образом. Моя проблема в том, что это может занять много времени при перечислении таких классов, как CIM_DataFile или Win32_Directory. Вот почему я пытаюсь использовать асинхронное перечисление (используя событие ManagementOperationObserver.ObjectReady), но я не могу заставить его работать - приложение зависает. – 2009-12-10 22:13:50

+0

Вам нужно отобразить все данные? Можете ли вы каким-то образом его разбивать на страницы? –

+0

Иногда мне нужно будет отобразить все данные. Синхронное перечисление работает хорошо, но для Cim_DataFile асинхронное перечисление будет правильным выбором. Я смог использовать один и тот же асинхронный код и отправить данные в RichTextBox, но я также хотел бы заполнить DataGridView. Я полагаю, что это связано с DataGridView, но я озадачен тем, что у меня нет каких-либо исключений, приложение просто зависает, а одно и то же приложение отлично работает, когда я заменяю DataGridView RichTextBox и добавляю строки текста из Observer_ObjectReady. – 2009-12-11 15:42:48

0

Может быть исключением выбрасывают? Winforms не просто останавливают выполнение, когда генерируется исключение, этот метод прерывается, и событие, которое вы должны вручную обрабатывать, увеличивается. Вам нужно будет создать обработчик исключений, чтобы увидеть их!

Application.ThreadException += 
    new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 

Я предполагаю, что вы получаете исключение из чего-то - это может быть, что не вызывая .Подключать() на ManagementScope, что вы также не создающим дают вам неисправность ... следующая часть того, что я использую, и она работает для меня в асинхронном режиме. YMMV.

ManagementScope ms = new ManagementScope(@"\\localhost\root\cimv2\"); 
ms.Connect(); 

ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query); 
searcher.Get(observer); 

Также, как сказал Рубенс, проблема может быть связана с сеткой данных и добавлением одной строки за раз. Рассматривали ли вы возможность добавления элементов в коллекцию в событии ObjectReady наблюдателя, а затем привязки данных к ним в событии Completed наблюдателя?

Третья возможность может быть комбинацией исключений, которые не отображаются, и события обратного вызова, выполненные из потока, отличного от UI. Попытка обновить элементы управления пользовательского интерфейса из другого потока - это большой нет-нет. См. «How do I make event callbacks into my winforms thread safe?»

Надейтесь на что-то полезное для вас. :-)