您的位置:首页 > 产品设计 > UI/UE

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

2008-02-05 09:18 579 查看
刚刚编写了线程安全的代码,该方法示例执行 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. 这篇文章。本文在其基础之上有所改进,把正在的执行逻辑从线程安全处理方法中分离出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐