【发布时间】:2012-10-18 13:50:49
【问题描述】:
我有两种形式,一种是MainForm,另一种是DebugForm。 MainForm 有一个按钮,可以像这样设置和显示 DebugForm,并将引用传递给已经打开的 SerialPort:
private DebugForm DebugForm; //Field
private void menuToolsDebugger_Click(object sender, EventArgs e)
{
if (DebugForm != null)
{
DebugForm.BringToFront();
return;
}
DebugForm = new DebugForm(Connection);
DebugForm.Closed += delegate
{
WindowState = FormWindowState.Normal;
DebugForm = null;
};
DebugForm.Show();
}
在 DebugForm 中,我附加了一个方法来处理串行端口连接的DataReceived 事件(在 DebugForm 的构造函数中):
public DebugForm(SerialPort connection)
{
InitializeComponent();
Connection = connection;
Connection.DataReceived += Connection_DataReceived;
}
然后在Connection_DataReceived方法中,我在DebugForm中更新了一个TextBox,也就是使用Invoke进行更新:
private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
_buffer = Connection.ReadExisting();
Invoke(new EventHandler(AddReceivedPacketToTextBox));
}
但我有一个问题。一旦我关闭 DebugForm,它就会在 Invoke(new EventHandler(AddReceivedPacketToTextBox)); 行上抛出一个 ObjectDisposedException。
我该如何解决这个问题?欢迎任何提示/帮助!
更新
我发现如果我在按钮事件 click 中删除事件,并在该按钮单击中关闭表单,一切都很好,我的调试表单毫无例外地被关闭......多么奇怪!
private void button1_Click(object sender, EventArgs e)
{
Connection.DataReceived -= Connection_DebugDataReceived;
this.Close();
}
【问题讨论】:
-
好吧,如果你不能在 Dispose() 方法中分离(为什么?!)你可以在 OnClosed() 方法中进行(它肯定会被调用)并添加一个签入Connection_DataReceived 仅在 IsDisposed 为 false 时调用 Invoke()。
-
我将 evnet detach 放在
Dispose()方法中,但我遇到了同样的问题。我什至尝试在Invoke之前添加if(Dispoing == false)也没有帮助。 -
不是 Disposed 而是 IsDisposed
-
嗯,它可能会在 Invoke() 期间关闭 ,我不知道框架将如何处理这个问题。您是否尝试过使用 BeginInvoke?如果你从 OnClosed() 中分离它是否有效?
-
我不喜欢您在 MainForm 中处理 Debug.Closed 的方式。您应该覆盖 OnClosed 并与那里的事件断开连接。这就是为什么,您的 DebugForm 连接到事件,因此,它也应该与事件断开连接(谁对此负责?)
标签: c# .net winforms multithreading invoke