I'm modifying an application written in C# that makes heavy-use of multi-threading to play audio files and display images to a user. Given that it is multi-threaded, I need to use the Invoke method often to change form elements. I'm running into a pattern that I'm not very comfortable with, where I find myself writing frequent, small, delegate methods that typically only do one thing. An example of this is as follows:
delegate void setImageCallback(Image img);
private void setImage(Image img)
{
this.pictureBox1.Image = img;
}
private void someOtherMethod()
{
...
if (this.pictureBox1.InvokeRequired)
{
this.Invoke(new setImageCallback(setImage), Image.FromFile("example.png");
}
else
{
this.pictureBox1.Image = Image.FromFile("example.png");
}
...
}
How do people generally handle these situations, so that you don't find yourself writing an absurd number of delegates and methods just to remain thread-safe? Obviously, consolidation of similar methods is great, but if I potentially need to update every form element on my form, I don't want to have a "modify" delegate and method for each of these.
Thanks.
A good example is here .
this.BeginInvoke( (Action) (()=>
{
pictureBox1.Image = Image.FromFile("example.png");
}));
You definitely don't need a separate delegate for each. You can use Action
delegates and lambda expressions to simplify it, like this:
private void SomeOtherMethod()
{
Action action = () => pictureBox1.Image = Image.FromFile("example.png");
if (pictureBox1.InvokeRequired)
{
Invoke(action);
}
else
{
action();
}
}
Or you can separate out the if
statement and InvokeRequired
check and generalize it even more, like this:
public static void InvokeIfRequired(Control control, Action action)
{
if (control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
private void SomeOtherMethod()
{
InvokeIfRequired(() => pictureBox1.Image = Image.FromFile("example.png");
}
I would use the MethodInvoker
type in conjunction with an anonymous method or lambda expression. I would also build the invocation logic into the method itself, rather than using a separate thread-safe method:
void SomeMethod(/* with whatever args */) {
if (InvokeRequired)
Invoke(new MethodInvoker(() => SomeMethod(/* args used to call method */)));
else
// the method body itself
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.