【发布时间】:2013-11-17 04:28:11
【问题描述】:
我有一个类似“ClientSocket.cs”的类
class ClientSocket {
public delegate void ConnectHandler(object sender, EventArgs e);
public event ConnectHandler ConnectEvent = delegate { };
protected void OnConnectEvent(EventArgs e) {
ConnectHandler ev = ConnectEvent;
ev(this, e);
}
}
还有另一个类“myForm.cs”
public partial class myForm : Form {
private ClientSocket client;
private void button1_Click(object sender, EventArgs e) {
client = new ClientSocket();
client.ConnectEvent += myForm_OnConnectEvent;
client.connect();
}
// Handler for ConnectEvent
private void myForm_OnConnectEvent(object sender, EventArgs e) {
//this.BeginInvoke((MethodInvoker)delegate { writeLog("Connected"); });
writeLog("Connected");
}
// Function that write a log string to a TextBox
public writeLog(string log) {
guiTextBox.AppendText(log);
}
}
问题来了。 我尝试使用 BeginInvoke 调用 writeLog 或直接调用它。有时我在写入 guiTextBox 时会收到 InvalidOperationException。 我不明白为什么我会收到那条消息。该事件由 ClientSocket 对象触发,但事件处理程序是相对于主 UI 线程 (myForm)。
我可以避免对我班级的每个 EventHandler 使用 BeginInvoke/Invoke 吗?
编辑:我了解有什么区别,现在我尝试了解调用事件的最佳做法。
在 BASE 类中引发事件(在这种情况下为 ClientSocket)时,我是否应该将 BeginInvoke/Invoke 方法放入
protected void OnConnectEvent(EventArgs e) {
ConnectHandler ev = ConnectEvent;
this.BeginInvoke((MethodInvoker)delegate { ev(this, e);});
}
或者我应该把它当我使用那个对象并向那个处理程序添加一个监听器
// Handler for ConnectEvent used in GUI (myForm)
private void myForm_OnConnectEvent(object sender, EventArgs e) {
this.BeginInvoke((MethodInvoker)delegate { writeLog("Connected"); });
}
干杯
【问题讨论】:
-
完整的解释见这个 MSDN 帖子,msdn.microsoft.com/en-us/library/ms171728%28v=vs.85%29.aspx
-
MSDN 很清楚这一点。现在我只想知道使用 BeginInvoke 的最佳实践。我应该在 ClientSocket 的 EventHandler 中还是在 myForm 中调用“BeginInvoke”?
-
引用的示例调用表单的方法来检查 textBox1.InvokeRequired 是否为真,然后继续设置文本。我不完全理解您的问题,因为示例中没有使用
BeginInvoke。 -
我了解这个例子,我想了解使用 BeginInvoke/Invoke 的最佳实践是什么。我试图解释我最好的(编辑)
标签: c# user-interface invoke