我在Windows窗体应用程序中遇到UI问题。我知道互联网上有关于这个问题的无数帖子,但我仍然找不到合适的解决方案。
我有这个方法:
private void AddContactTile(ContactTile c)
{
if (mainPanel.InvokeRequired)
{
AddContactTileDelegate ctdelegate = new AddContactTileDelegate(AddContactTile);
mainPanel.BeginInvoke(ctdelegate, c);
}
else
{
mainPanel.Controls.Add(c);
}
}
和这个方法:
private void ChangeTileStatus(string userid)
{
ContactTile tile = contactTiles.Find(x => x.Key == userid).Value;
if (tile.statusLabel.InvokeRequired)
{
ChangeTileStatusDelegate ctsdelegate = new ChangeTileStatusDelegate(ChangeTileStatus);
tile.statusLabel.BeginInvoke(ctsdelegate, userid);
}
else
{
if (contacts.ContainsKey(userid))
{
tile.statusLabel.Visible = contacts[userid].IsAvailable;
tile.Refresh();
}
}
}
这两个都在事件处理程序中调用。现在,因为可能同时引发事件,所以我在statusLabel
方法的AddContactTile
控件上收到了无效的跨线程操作消息。
有没有人知道如何正确同步这些访问?感谢。
AddContact
方法的代码:
public void AddContact(FacebookUser user)
{
contacts[user.id].DisplayPictureAvailable += new EventHandler<UserEventArgs>(Contacts_DisplayPictureAvailable);
contacts[user.id].StatusChanged += new EventHandler<UserEventArgs>(Contacts_StatusChanged);
ContactTile c = new ContactTile(user.name, user.id) { Location = new Point(0, contactTiles.Count == 0 ? 0 : contactTiles.Last().Value.Bounds.Bottom) };
contactTiles.Add(new KeyValuePair<string, ContactTile>(user.id, c));
AddContactTile(c);
}
堆栈追踪:
StackTrace " at System.Windows.Forms.Control.get_Handle() at
System.Windows.Forms.Control.UpdateChildZOrder(Control ctl) at
System.Windows.Forms.Control.WmCreate(Message& m) at
System.Windows.Forms.Control.WndProc(Message& m) at
System.Windows.Forms.Label.WndProc(Message& m) at
System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)"
答案 0 :(得分:3)
ContactTile
是在UI线程以外的线程中创建的,但是在AddContactTile
中你将它添加到mainPanel's
线程中,我认为它是UI线程。遵循此规则"It is unsafe to call a control from a thread other than the one that created the control",尝试在UI线程中创建ContactTile
个实例。
答案 1 :(得分:1)
您可以在拨打mutex.WaitOne();
之前使用互斥锁并拨打.BeginInvoke(...);
,或者从代表本身检查互斥锁。
http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx