我在一个成员中得到一个“无效的跨线程操作”,但在另一个成员中却没有,它们都属于同一个表单,我相信是同一个 UI 线程。这些成员是uxServerGroup
和uxServerListen
。当我更改它上面的文本时,uxServerGroup.ValuesSecondary.Heading
它工作正常,我没有得到一个跨线程异常。但是当我尝试启用uxServerListen
按钮时,我确实得到了一个。为什么?
我可能应该注意到,这两个组件都属于 Krypton Toolkit,它们不是标准的 Windows 窗体。
这是我拥有的代码示例:
MainForm.cs:
public partial class MainForm : Form {
public MainForm() {
InitializeComponent();
SomeClass.ObjectStateChanged += new ObjectStateEventHandler(SomeClass_ObjectStateChanged);
}
private void uxServerListen_Click(object sender, EventArgs e) {
uxServerListen.Enabled = false;
ClassHandler ch = ClassHandler();
ch.Initialize();
}
private void SomeClass_ObjectStateChanged(Enum e1, Enum e2) {
switch(e1) {
case E1.TypeA:
HandleTypeAObjectChanges(e1);
break;
case E1.TypeB:
HandleTypeBObjectChanges(e2);
break;
}
}
private void HandleTypeAObjectChanges(Enum e2) {
switch(e2) {
case E2.ModeA:
uxServerGroup.ValuesSecondary.Image = Resources.StatusSuccess16;
break;
case E2.ModeB:
uxServerGroup.ValuesSecondary.Image = Resources.StatusFailure16;
uxServerListen.Enabled = true;
break;
}
}
}
SomeClass.cs:
public delegate void ObjectStateEventHandler(Enum e1, Enum e2);
public static class SomeClass {
public static event ObjectStateEventHandler ObjectStateChanged;
internal static E1 e1;
internal static void ObjectStateChanged(Enum e2) {
if(ConnectionStateChanged != null) {
ConnectionStateChanged(e1, e2);
}
}
}
类处理程序.cs:
public class ClassHandler {
public ClassHandler() {
// (...)
}
public void Initialize() {
Thread thread = new Thread(new ThreadStart(SomeMethod));
thread.Start();
}
private void SomeMethod() {
SomeClass.ObjectStateChanged(E2.ModeB);
}
}
经过大量搜索,我最终将其修复为:
private void SomeClass_ObjectStateChanged(Enum e1, Enum e2) {
if(InvokeRequired) {
Invoke(new MethodInvoker(() => {
switch(e1) {
case E1.TypeA:
HandleTypeAObjectChanges(e2);
break;
case E1.TypeB:
HandleTypeBObjectChanges(e2);
break;
}
}));
}
}
作为一个额外的问题,有人可以解释一下(里面的东西MethodInvoker
):
new MethodInvoker(() => { /* (...) */ })