2012-02-07 6 views
0

파일의 변경 사항을 확인하는 프로그램이 있습니다. 파일이 변경되면 읽음으로써 일부 레이블이 업데이트됩니다. "하지만 다른 스레드에서 스레드의 요소를 변경하려고하기 때문에 충돌이 발생합니다"~ 또는 그렇게 생각합니다. 어떤 아이디어?filesystemeventhandler에서 Form1 요소에 액세스하십시오.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
using System.Windows.Forms; 
using System.IO; 
using System.Threading.Tasks; 


namespace RoomAutomation 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     public void readfile_Click(object sender, EventArgs e) 
     { 

      string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Dandrews\control.txt"); 
      FileSystemWatcher fsw = new FileSystemWatcher(); 
      fsw.Path = @"C:\Users\Dandrews\"; 
      fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | 
          NotifyFilters.DirectoryName | NotifyFilters.FileName; 
      fsw.Changed += new FileSystemEventHandler(OnChanged); 
      fsw.EnableRaisingEvents = true; 
      if (lines[0] == "1:lights") 
      { 
       Lights.Text = "Lights are on."; 
      } 
      if (lines[0] == "0:lights") 
      { 
       Lights.Text = "Lights are off."; 
      } 
      if (lines[1] == "1:camera") 
      { 
      Camera.Text = "Camera is on."; 
      } 
      if (lines[1] == "0:camera") 
      { 
       Camera.Text = "Camera is off."; 
      } 
      if (lines[2] == "1:speakers") 
      { 
       Speakers.Text = "Speakers are on."; 
      } 
      if (lines[2] == "0:speakers") 
      { 
       Speakers.Text = "Speakers are off."; 
      } 
      if (lines[3] == "1:playlist") 
      { 
       Playlist.Text = "Playlist is on."; 
      } 
      if (lines[3] == "0:playlist") 
      { 
       Playlist.Text = "Playlist is off."; 
      }   
     } 
     private void OnChanged(object source, FileSystemEventArgs e) 
     {    
      Console.Write("Changes"); 
      //Lights.Text = "New label Text"; 

     } 
    } 
} 

`

+0

예외는 무엇입니까? 그리고 * 왜 * 질문에 따옴표를 붙였습니까? –

+0

@ M.Babcock 그래, ive notive 내가 당신이 그것에 반응하는 것을 볼 수 있기 전에 나는 그를 위해 빨리 그 코드를 읽었다. :) – warbio

+0

System.Windows.Forms.dll에서 'System.InvalidOperationException'형식의 첫 번째 예외가 발생했습니다. '[6316] RoomAutomation.vshost.exe : Managed (v4.0.30319)'프로그램이 코드 0 (0x0). 인용문은 문제가 있다고 생각하는 것 주위에 있습니다. :) – Dandrews

답변

0

.NET 2.0 이상 doesn't allow you to access UI elements from other threads. 컨트롤에서 실행할 코드를 호출해야합니다. 당신이 코드 porting.NET 1.1 인 경우에, 여기 당신의 인생을 더 쉽게 만드는 간단한 해킹입니다 :은 FileSystemWatcher는 스레드 풀 스레드에서 해당 이벤트를 발생하기 때문이다

http://codebetter.com/jeremymiller/2006/11/06/using-anonymous-methods-with-control-invoke/

+0

.NET 1.1 코드를 포팅하지 않습니다. .NET 2.0 이상을 사용하는 쉬운 해결 방법을 찾으십시오. – Dandrews

+0

.NET 2.0 및 그 이후의 쉬운 해결 방법 - 이전에는 그렇게했기 때문에 마이그레이션에 대해서만 언급합니다. :-) 덜 쉬운 해결 방법은 [BackgroundWorker] (http://msdn.microsoft.com/en-us/library/cc221403(v=v9).aspx) –

+0

@ user1116969 사용할 수 있습니다./is/the .NET 2.0 및 그 이후의 쉬운 해결 방법 - 이전에는 마이그레이션을 수행했기 때문에 마이그레이션에 대해서만 언급합니다. :-) FSW의 OnChanged 이벤트에서 호출하고자하는 코드가 무엇이든 익명의 대리자를 랩핑하고 폼 요소 인 Invoke 메서드에 전달합니다. 멋지고 쉬운 해결책입니다. 또 다른 옵션은 [BackgroundWorker] (http://msdn.microsoft.com/en-us/library/cc221403(v=v9.aspx) .aspx)를 사용하고 ProgressChanged 이벤트를 구현하는 것입니다. 접근 방식이 가장 효과적입니다. 희망이 도움이! –

1

합니다. 자연스럽게 파일 시스템 이벤트가 비동기 적으로 발생합니다. 이벤트 처리기의 모든 UI 구성 요소에 직접 액세스 할 수는 없으며 스레드로부터 안전하지 않습니다. InvalidOperationException은 사용자가 할 수 없다는 것을 알려주는 것입니다.

이 한 줄의 코드를 추가 걸립니다 고정 : 폼의 UI 스레드 생성 스레드 이벤트 핸들러 호출을 마샬링은 FileSystemWatcher 강제

 fsw.SynchronizingObject = this; 

한다. 이것은 반드시 최상의 솔루션은 아니지만 호출을 마샬링하는 데 소요되는 오버 헤드가 많습니다. 그러나 당신은 이 있으니이 코드로 각 이벤트마다 마샬링해야하므로이 솔루션을 사용하는 것이 좋습니다.

관련 문제