2012-08-11 64 views
1

enter image description here
我想刷新我的datagridview,如果有特定的xml文件的變化。我有一個FileSystemWatcher來查找文件中的任何更改並調用datagirdview函數來重新加載xml數據。FileSystemWatcher無效的數據異常錯誤

當我嘗試,我得到Invalid data Exception error有人請告訴我在這裏做什麼錯誤?

public Form1() 
      { 
       InitializeComponent(); 
       FileSystemWatcher watcher = new FileSystemWatcher(); 

       watcher.Path = @"C:\test"; 
       watcher.Changed += fileSystemWatcher1_Changed; 
       watcher.EnableRaisingEvents = true; 
       //watches only Person.xml 
       watcher.Filter = "Person.xml"; 

       //watches all files with a .xml extension 
       watcher.Filter = "*.xml"; 

      } 

      private const string filePath = @"C:\test\Person.xml"; 
      private void LoadDatagrid() 
      { 
       try 
       { 
        using (XmlReader xmlFile = XmlReader.Create(filePath, new XmlReaderSettings())) 
        { 
         DataSet ds = new DataSet(); 
         ds.ReadXml(xmlFile); 
         dataGridView1.DataSource = ds.Tables[0]; //Here is the problem 
        } 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.ToString()); 
       } 
      } 

      private void Form1_Load(object sender, EventArgs e) 
      { 
       LoadDatagrid(); 
      } 

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e) 
      { 
       LoadDatagrid(); 
      } 

回答

2

這是因爲FileSystemWatcher在不同的線程上運行,而不是在UI線程上運行。在winforms應用程序中,只有UI線程(程序的主線程)才能與Visual Constrols交互。如果您需要從另一個線程與視覺控件進行交互,則必須在目標控件上調用Invoke

// this event will be fired from the thread where FileSystemWatcher is running. 
private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e) 
{ 
     // Call Invoke on the current form, so the LoadDataGrid method 
     // will be executed on the main UI thread. 
     this.Invoke(new Action(()=> LoadDatagrid())); 
} 
1

的FileSystemWatcher的是在一個單獨的線程中運行,而不是在UI線程。爲了維護線程安全,.NET阻止您從非UI線程(即創建表單組件的那個線程)更新UI。

要輕鬆解決該問題,請從fileSystemWatcher1_Changed事件調用目標Form的MethodInvoker方法。有關如何執行此操作的更多詳細信息,請參閱MethodInvoker Delegate。還有其他的選擇,如何做到這一點,包括。設置一個同步的(即線程安全的)對象來保存任何事件的結果/標記,但是這不需要改變表單代碼(即在遊戲的情況下,可以輪詢主遊戲循環中的同步對象等) )。

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e) 
{ 
    // Invoke an anonymous method on the thread of the form. 
    this.Invoke((MethodInvoker) delegate 
    { 
     this.LoadDataGrid(); 
    }); 
} 

編輯:更正了以前在代表中有問題的答案,LoadDataGrid缺少這個。它不會像這樣解決。

相關問題