2012-08-11 2 views
1

enter image description here
특정 xml 파일에 변경 사항이있는 경우 내 datagridview를 새로 고치고 싶습니다. 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 스레드 (프로그램의 주 스레드) 만 시각적 구성 요소와 상호 작용할 수 있습니다. 이 경우와 같이 다른 스레드의 시각적 컨트롤과 상호 작용해야하는 경우 대상 컨트롤에서 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을 참조하십시오. 이를 수행하는 방법에는 다른 옵션이 있습니다 (incl. 어떤 이벤트의 결과/플래그를 유지하기 위해 동기화 된 (즉, thread-safe) 오브젝트를 설정하지만, 이것은 폼 코드를 변경할 필요가 없다. (즉, 게임의 경우 메인 게임 루프에서 동기화 된 오브젝트를 폴링 할 수있다.).

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에 누락되었습니다. 그 자체로 해결되지는 않을 것입니다.