C# 3.0 and after:
An extension method would generally be the way to go, since you're always going to want to perform an action on an ISynchronizeInvoke
interface implementation, it's a good design choice.
You can also take advantage of anonymous methods (closures) to account for the fact that you don't know what parameters to pass to the extension method; the closure will capture the state of everything needed.
// Extension method.
static void SynchronizedInvoke(this ISynchronizeInvoke sync, Action action)
{
// If the invoke is not required, then invoke here and get out.
if (!sync.InvokeRequired)
{
// Execute action.
action();
// Get out.
return;
}
// Marshal to the required context.
sync.Invoke(action, new object[] { });
}
You'd then call it like this:
private void SetText(string text)
{
textBox1.SynchronizedInvoke(() => textBox1.Text = text);
}
Here, the closure is over the text
parameter, that state is captured and passed as part of the Action
delegate passed to the extension method.
Before C# 3.0:
You don't have the luxury of lambda expressions, but you can still generalize the code. It's pretty much the same, but not an extension method:
static void SynchronizedInvoke(ISynchronizeInvoke sync, Action action)
{
// If the invoke is not required, then invoke here and get out.
if (!sync.InvokeRequired)
{
// Execute action.
action();
// Get out.
return;
}
// Marshal to the required context.
sync.Invoke(action, new object[] { });
}
And then you call it with anonymous method syntax:
private void SetText(string text)
{
SynchronizedInvoke(textBox1, delegate() { textBox1.Text = text; });
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…