开发者

The calling thread cannot access this object because a different thread

开发者 https://www.devze.com 2023-04-02 09:23 出处:网络
Every time I try to set the any of the label text properties, it complains about not being in the same thread. That\'s kind of confusing since the code is inside an event handler.

Every time I try to set the any of the label text properties, it complains about not being in the same thread. That's kind of confusing since the code is inside an event handler.

The same works alright with the pictureBox.

How can this be modified to work as expected?

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());
        开发者_Go百科}
    }
}

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));
        }
    }

}


My guess would be that AttendanceControlDevice is raising the event on a background thread, or (more likely) the Repository is raising some event on a background thread and that is propagating through the AttendanceControlDevice and thus you are still on a background thread when the event fires.

You probably know this, but you should check for InvokeRequired and Invoke/BeginInvoke appropriately.


It maybe because of thread which AttendanceControlDevice on is different with current thread.

You should make the thread-safe call to Windows Forms Controls in this case as you may know (MSDN link: http://msdn.microsoft.com/en-us/library/ms171728.aspx)

0

精彩评论

暂无评论...
验证码 换一张
取 消