2011-09-06 3 views
0

레이블 텍스트 속성 중 하나를 설정하려고 할 때마다 동일한 스레드가 아닌 것에 대해 불평합니다. 코드가 이벤트 처리기 안에 있기 때문에 다소 혼란 스럽습니다.다른 스레드가 있기 때문에 호출 스레드가이 개체에 액세스 할 수 없습니다.

pictureBox과 똑같은 작동.

예상대로 작동하려면 어떻게 수정해야합니까?

public partial class Form3 : Form 
{ 
    AttendanceControlDevice control; 

    public Form3() 
    { 
     InitializeComponent(); 
    } 

    private void Form3_Load(object sender, EventArgs e) 
    { 
     string conn = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; 
     control = new AttendanceControlDevice(new EmployeesRepository(new SqlConnection(conn)), new zkemkeeper.CZKEMClass()); 
     control.OnEmployeeChecked += new EventHandler<EmployeeCheckedEventArgs>(control_OnEmployeeChecked); 
     control.Connect(ConfigurationManager.AppSettings["ip"], int.Parse(ConfigurationManager.AppSettings["port"])); 
    } 

    void control_OnEmployeeChecked(object sender, EmployeeCheckedEventArgs e) 
    { 
     try 
     { 
      label1.Text = e.Employee.Id; 
      label2.Text = e.Employee.Name; 
      pictureBox1.Image = Image.FromFile(e.Employee.Picture); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
    } 
} 

public class AttendanceControlDevice 
{ 
    ... 

    public bool Connect(string ip,int port) 
    { 
     _connected = _commChannel.Connect_Net(ip, port); 
     if(!_connected) 
     { 
      _commChannel.GetLastError(ref _lastError); 
      Error = _errorDescriptions[_lastError]; 
     }else{ 
      _commChannel.RegEvent(1, (int)deviceEvents.OnAttTransaction); 
     _commChannel.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(commChannel_OnAttTransactionEx); 
     } 
     return _connected; 
    } 


    void commChannel_OnAttTransactionEx(string EnrollNumber, int IsInValid, int AttState, int VerifyMethod, int Year, int Month, int Day, int Hour, int Minute, int Second, int WorkCode) 
    { 
     if(OnEmployeeChecked != null) 
     { 
      Employee employee = null; 

      try{ 
       employee = _employees.Get(EnrollNumber); 
      } 
      catch { 
       employee = new Employee(EnrollNumber, "Error while reading the data", ""); 
      } 

      if (employee == null) employee = new Employee(EnrollNumber, "Could not match the id", ""); 

      OnEmployeeChecked.Invoke(this, new EmployeeCheckedEventArgs(employee)); 
     } 
    } 

}

답변

2

내 생각은 AttendanceControlDevice 백그라운드 스레드에서 이벤트를 발생되거나, (가능성이) 저장소는 백그라운드 스레드에서 어떤 이벤트를 발생하고, 그이 AttendanceControlDevice를 통해 전파되는 것 및 따라서 이벤트가 시작될 때 여전히 백그라운드 스레드에 있습니다.

아마 알겠지만 InvokeRequired와 Invoke/BeginInvoke를 적절하게 확인해야합니다.

+0

을 ... : P CZKEMClass이 세 번째입니다 파티 라이브러리는 일부 장치와 통신하는 데 사용됩니다. AttendanceControlDevice는 특정 이벤트를 구독하고 차례로 자신의 이벤트를 발생시킵니다. 나는 그것을 보여줄 수있는 글을 업데이트했다. – max

+0

추가 된 코드는 AttendanceControlDevice가 이벤트를 발생시키는 업스트림 코드가 백그라운드 스레드에서 실행 중이기 때문에 백그라운드 스레드에있는 이벤트에 대한 의문점을 심화시킵니다 (그러나 확인하지는 않습니다). 백그라운드 스레드에서 UI 컨트롤을 안전하게 호출하는 방법은 다음을 참조하십시오. http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx –

0

AttendanceControlDevice가 현재 스레드와 다른 스레드 때문일 수 있습니다.

윈도우 당신이 (MSDN 링크 : http://msdn.microsoft.com/en-us/library/ms171728.aspx) 알 수 있으므로이 경우에는 Forms 컨트롤에 당신은 스레드 안전 호출을해야

사실 나는 그것을 알고하지 않았다

관련 문제