その「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) でイベントを RAISING するときに 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"); });
}
乾杯