栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何从另一个线程更新GUI?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何从另一个线程更新GUI?

对于.NET 2.0,这是我编写的大量代码,完全可以实现您想要的功能,并且可以用于a的任何属性

Control

private delegate void SetControlPropertyThreadSafeDelegate(    Control control,     string propertyName,     object propertyValue);public static void SetControlPropertyThreadSafe(    Control control,     string propertyName,     object propertyValue){  if (control.InvokeRequired)  {    control.Invoke(new SetControlPropertyThreadSafeDelegate        (SetControlPropertyThreadSafe),     new object[] { control, propertyName, propertyValue });  }  else  {    control.GetType().InvokeMember(        propertyName,         BindingFlags.SetProperty,         null,         control,         new object[] { propertyValue });  }}

这样称呼它:

// thread-safe equivalent of// myLabel.Text = status;SetControlPropertyThreadSafe(myLabel, "Text", status);

如果您使用的是.NET 3.0或更高版本,则可以将上述方法重写为

Control
该类的扩展方法,从而将调用简化为:

myLabel.SetPropertyThreadSafe("Text", status);

2010年5月10日更新:

对于.NET 3.0,您应该使用以下代码:

private delegate void SetPropertyThreadSafeDelegate<TResult>(    Control @this,     expression<Func<TResult>> property,     TResult value);public static void SetPropertyThreadSafe<TResult>(    this Control @this,     expression<Func<TResult>> property,     TResult value){  var propertyInfo = (property.Body as Memberexpression).Member       as PropertyInfo;  if (propertyInfo == null ||      !@this.GetType().IsSubclassOf(propertyInfo.ReflectedType) ||      @this.GetType().GetProperty(          propertyInfo.Name,propertyInfo.PropertyType) == null)  {    throw new ArgumentException("The lambda expression 'property' must reference a valid property on this Control.");  }  if (@this.InvokeRequired)  {      @this.Invoke(new SetPropertyThreadSafeDelegate<TResult>       (SetPropertyThreadSafe),       new object[] { @this, property, value });  }  else  {      @this.GetType().InvokeMember(          propertyInfo.Name,BindingFlags.SetProperty,null,@this,new object[] { value });  }}

它使用LINQ和lambda表达式允许更简洁,更简单和更安全的语法:

myLabel.SetPropertyThreadSafe(() => myLabel.Text, status); // status has to be a string or this will fail to compile

现在不仅在编译时检查属性名称,而且属性的类型也是如此,因此不可能(例如)为布尔型属性分配字符串值,从而导致运行时异常。

不幸的是,这并不能阻止任何人做愚蠢的事情,例如传递另一个

Control
人的财产和价值,所以下面的代码会很高兴地被编译:

myLabel.SetPropertyThreadSafe(() => aForm.ShowIcon, false);

因此,我添加了运行时检查,以确保传递的属性确实属于

Control
调用该方法的属性。虽然不完美,但仍比.NET 2.0版本好很多。

如果有人对如何提高此代码的编译时安全性有任何进一步的建议,请发表评论!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/433052.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号