每当我尝试设置任何标签文本属性时,它都会抱怨不在同一个线程中。由于代码在事件处理程序中,所以有点令人困惑。
同样适用于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));
}
}
}
答案 0 :(得分:2)
我的猜测是AttendanceControlDevice在后台线程上引发事件,或者(更有可能)Repository在后台线程上引发一些事件并且通过AttendanceControlDevice传播,因此你仍然在后台线程上事件发生了。
你可能知道这一点,但你应该适当地检查InvokeRequired和Invoke / BeginInvoke。
答案 1 :(得分:0)
这可能是因为AttendanceControlDevice on的线程与当前线程不同。
在您知道的情况下,您应该在这种情况下对Windows窗体控件进行线程安全调用(MSDN链接:http://msdn.microsoft.com/en-us/library/ms171728.aspx)