.NET 2.0 中,两种如何创建一个线程安全的 UI 的方法

文/egeye  出处/博客园

刚刚编写了线程安全的代码,该方法示例执行 Windowns Forms Event Handler 跨线程 UI 调用,BindXmlDocumentToTreeView 是一个绑定 Xml 到一个 TreeView 控件的方法,其可以很好的工作于不同的线程。它首先检查 Control(TreeView)的 InvokeRequired 属性,以判断是否是与 UI 线程不同的线程调用,然后使用 TreadPool 工具,并借助 .Net 2.0 中的匿名代理,使用 TreadStart 委托。方法中调用了真正的执行方法(BindXmlDocumentToTreeViewInternal)。

方法一:
public static void BindXmlDocumentToTreeView(XmlDocument xmlDocument, TreeView tv)
        {
            if (tv.InvokeRequired)
            {
                ThreadPool.QueueUserWorkItem(delegate(object obj)
                {
                    tv.Invoke(new ThreadStart(delegate()
                    {
                        BindXmlDocumentToTreeViewInternal(xmlDocument, tv);
                    }));
                });
            }
            else
            {
                BindXmlDocumentToTreeViewInternal(xmlDocument, tv);
            }
        }

        private static void BindXmlDocumentToTreeViewInternal(XmlDocument xmlDocument, TreeView tv)
        {
            if (xmlDocument != null && tv != null)
            {
                TreeNode root;
                root = AddTreeViewNode(xmlDocument.DocumentElement);
                tv.Nodes.Add(root);
            }
        }

这种方案使用了 TreadStart 代理,并使用线程池,可以很好的改善 UI 的性能,另外还有一种方式

方法二:
public static void BindXmlDocumentToTreeView(XmlDocument xmlDocument, TreeView tv)
        {
            if (tv.InvokeRequired)
            {
                tv.Invoke(new MethodInvoker(delegate { BindObjectParametersInternal(paramObject, node.Nodes); }));
            }
            else
            {
                BindObjectParametersInternal(paramObject, node.Nodes);
            }
        }

这种方案使用了 MethodInvoker 同事没有使用线程池工具,两种方法可以达到同样的效果,具体选用哪种方式,可能根据大家的喜欢和要求,比如是否使用线程池,ThreadStart 代理与 MethodInvoker 并无本质差异,他们都是无参数代理,你也可以定义自己的代理,因为代理中,我们并没有定义真正执行方法的参数,这也是我比较喜欢的一个原因。

关于线程安全 UI 方法,以及匿名代理,大家可以参考 Roy Osherove 的博客,阅读 The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner. 这篇文章。本文在其基础之上有所改进,把正在的执行逻辑从线程安全处理方法中分离出来。

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Visual Studio.NET] 的这些文章也感兴趣:

Microsoft Visual Studio下的Windows Live工具(7月CTP版)
提高ASP.Net应用程序性能的十大方法(一)
微软Enterprise Library开源了
微软发布Enterprise Library 4.1和Unity 1.2
深入学习heritrix---体系结构(Overview of the crawler)
揭开HTML 5工作草稿的神秘面纱
SCSF 系列:Smart Client Software Factory 中 MVP 模式的应用
Chart Controls 简介与下载点
BlogEngine.Net架构与源代码分析系列part7:Web2.0特性——Pingback&Trackba
解决大批量数据TransactionScope出错问题