避免InvokeRequired(3)
接上篇
原文:http://www.codeproject.com/KB/cs/AvoidingInvokeRequired.aspx
(转载请注明原文出处!)
http://www.whitejadesoft.com/CharlesJia/
“UIThread”模式,或者问题的最终解决之道
首先我像你展示“rabbit”:
//No parameters private void SetTextUsingPattern() { this.UIThread(delegate { this.text = "New Text"; }); } //With parameters private void SetTextUsingPatternParams(string text, int number, DateTime dateTime) { this.UIThread(delegate { MultiParams(text, number, dateTime); }); }
现在你将看到我的“trick”。这是一个简单的静态(static)类,只有一个方法。当然,
这是一个扩展方法(extension method),如果你对这有些异议,如“扩展方法不是纯
粹的面向对象编程”(”extension methods are not pure object orientated programming”),
我建议你去用Smalltalk,停止抱怨。或者用标准的帮助类(standard helper class),如你所愿。
除去注释,namespace和using,这个类如下所示:
static class FormExtensions { static public void UIThread(this Form form, MethodInvoker code) { if (form.InvokeRequired) { form.Invoke(code); return; } code.Invoke(); } }
就像你所看到的,这就像标准模式,尽可能的一般化。
这种解决方法的优点:
- 确实解决了问题。
- 对于Full and Compact Framework(with just one extra line)一样好使。
- 它很简单(就像一个using{}block!)。
- 不需要关注方法有没有参数。
- 如果你三个月后再来读,它仍然显得很清晰。
- 它使用了很多现代.NET(modern .NET)所提供的东东:匿名委托,扩展方法,lambda表示式(如果你想,请看后面部分),泛型类型推理?(generic type inference)。
缺点:
- 呃……还是你们来说吧,轻点拍啊
Points of Interest
这些代码需要完整的.NET Framework 3.5支持!如果在Compact Framework中使用,需要简单的声明一下MethodInvoker:
public delegate void MethodInvoker();
用lambda风格你能写更少的代码,如果你只想写一行代码的话,可以像这样……
private void SetTextUsingPatternParams(string text, int number, DateTime dateTime) { this.UIThread(()=> MultiParams(text, number, dateTime)); }
……仍然很清晰!
下载的文件中是一个简单的执行程序,展示了一些错误代码,如失败的,“标准模式”的,
还有我已经说过的“UIThread模式”的,还有两个工程,一个是完整的.NET Framework
工程,另一个是Compact Framework工程。
Charles Jia 完成翻译于 2009年07月16日 21:25:42
(转载请注明原文出处!)