避免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
                            (转载请注明原文出处!)
posted @ 2009-07-16 21:46  小小电工  阅读(1458)  评论(2编辑  收藏  举报