From what I've found in C#, the Control.Invoke method requires that you use a delegate with no input parameters. Is there any way around this? I would like to invoke a method to update the UI from another thread and pass to string parameters to it.
Invoke : Executes on the UI thread, but calling thread waits for completion before continuing. Control. BeginInvoke : Executes on the UI thread, and calling thread doesn't wait for completion.
Invoke is used to call a method on the UI thread — without it you can cause an exception by updating the UI from another thread. And so if InvokeRequires returns true it means that you are not running in the UI thread and should use Control. Invoke to run the call in the right thread.
Which version of C# are you using? If you are using C#3.5 you can use closures to avoid passing in parameters.
With C#3.5public static class ControlExtensions
{
public static TResult InvokeEx<TControl, TResult>(this TControl control,
Func<TControl, TResult> func)
where TControl : Control
{
return control.InvokeRequired
? (TResult)control.Invoke(func, control)
: func(control);
}
public static void InvokeEx<TControl>(this TControl control,
Action<TControl> func)
where TControl : Control
{
control.InvokeEx(c => { func(c); return c; });
}
public static void InvokeEx<TControl>(this TControl control, Action action)
where TControl : Control
{
control.InvokeEx(c => action());
}
}
Safely invoking code now becomes trivial.
this.InvokeEx(f => f.label1.Text = "Hello World");
this.InvokeEx(f => this.label1.Text = GetLabelText("HELLO_WORLD", var1));
this.InvokeEx(() => this.label1.Text = DateTime.Now.ToString());
public class MyForm : Form
{
private delegate void UpdateControlTextCallback(Control control, string text);
public void UpdateControlText(Control control, string text)
{
if (control.InvokeRequired)
{
control.Invoke(new UpdateControlTextCallback(UpdateControlText), control, text);
}
else
{
control.Text = text;
}
}
}
Using it simple, but you have to define more callbacks for more parameters.
this.UpdateControlText(label1, "Hello world");
Some more possibilities:
this.Invoke(new MethodInvoker(() => this.DoSomething(param1, param2)));
or
this.Invoke(new Action(() => this.DoSomething(param1, param2)));
or even
this.Invoke(new Func<YourType>(() => this.DoSomething(param1, param2)));
where the first option is the best one, because MethodInvoker is concepted for that purposes and has a better performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With