最方便的用法:
private void ViewMsg(string msg)
{
/*
control.Invoke(new SetControlTextDelegate((ct, v) => { ct.Text = v; }), new object[] { control, value });
=>
control.Invoke(new Action<Control, string>((ct, v) => { ct.Text = v; }), new object[] { control, value });
*/
this.rtb.Invoke(new Action<RichTextBox, string>((ct, v) => { ct.AppendText(v); ct.Refresh(); }),
new object[] { this.rtb, msg });
this.rtb.Invoke(new Action<string>((v) => { this.rtb.AppendText(v); this.rtb.Refresh(); }),
msg);
}
Because Invoke
/BeginInvoke
accepts Delegate
(rather than a typed delegate), you need to tell the compiler what type of delegate to create ; MethodInvoker
(2.0) or Action
(3.5) are common choices (note they have the same signature); like so:
control.Invoke((MethodInvoker)delegate{this.Text="Hi";});
If you need to pass in parameters, then "captured variables" are the way:
string message ="Hi";
control.Invoke((MethodInvoker)delegate{this.Text= message;});
(caveat: you need to be a bit cautious if using captures async, but sync is fine - i.e. the above is fine)
Another option is to write an extension method:
public static void Invoke(thisControl control,Action action){
control.Invoke((Delegate)action);}
then:
this.Invoke(delegate{this.Text="hi";});// or simce we are using C# 3.0this.Invoke(()=>{this.Text="hi";});
You can of course do the same with BeginInvoke
:
publicstaticvoidBeginInvoke(thisControl control,Action action){
control.BeginInvoke((Delegate)action);}
If you can't use C# 3.0, you could do the same with a regular instance method, presumably in a Form
base-class.