在这篇文章中:
http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx
作者使用以下方法对Windows窗体控件进行线程安全调用:
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
Run Code Online (Sandbox Code Playgroud)
是否有更短的方法来完成同样的事情?
cas*_*One 34
C#3.0以及之后:
扩展方法通常是要走的路,因为您总是希望在ISynchronizeInvoke接口实现上执行操作,这是一个很好的设计选择.
您还可以利用匿名方法(闭包)来解释您不知道要传递给扩展方法的参数的事实; 关闭将捕获所需的一切状态.
// 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[] { });
}
Run Code Online (Sandbox Code Playgroud)
然后你会这样称呼它:
private void SetText(string text)
{
textBox1.SynchronizedInvoke(() => textBox1.Text = text);
}
Run Code Online (Sandbox Code Playgroud)
这里,闭包在text参数上,该状态被捕获并作为传递给扩展方法的Action委托的一部分传递.
在C#3.0之前:
你没有lambda表达式的奢侈,但你仍然可以概括代码.它几乎相同,但不是扩展方法:
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[] { });
}
Run Code Online (Sandbox Code Playgroud)
然后用匿名方法语法调用它:
private void SetText(string text)
{
SynchronizedInvoke(textBox1, delegate() { textBox1.Text = text; });
}
Run Code Online (Sandbox Code Playgroud)
1)使用匿名代表
private void SetText(string text)
{
if (this.InvokeRequired)
{
Invoke(new MethodInvoker(delegate() {
SetText(text);
}));
}
else
{
this.textBox1.Text = text;
}
}
Run Code Online (Sandbox Code Playgroud)
2)AOP方法
[RunInUIThread]
private void SetText(string text)
{
this.textBox1.Text = text;
}
Run Code Online (Sandbox Code Playgroud)
http://weblogs.asp.net/rosherove/archive/2007/05.aspx?PageIndex=2
3)使用lambda表达式(由其他人概述).
编辑:我应该提到我不会认为这是最佳做法
如果使用的是3.5,则可以使扩展方法达到以下效果:
public static void SafeInvoke(this Control control, Action handler) {
if (control.InvokeRequired) {
control.Invoke(handler);
}
else {
handler();
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上是从:这里
然后像这样使用它:
textBox1.SafeInvoke(() => .... );
Run Code Online (Sandbox Code Playgroud)
当然,请修改扩展名等以供您使用。