Label从另一个更新a的最简单方法是Thread什么?
Label
Thread
我Form正在上运行thread1,然后从中启动另一个线程(thread2)。
Form
thread1
thread2
在thread2处理某些文件时,我想用的工作状态更新Label上的。Form``thread2
Form``thread2
我该怎么办?
对于.NET 2.0,这是我编写的大量代码,完全可以实现您想要的功能,并且可以用于a的任何属性Control:
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版本好很多。
如果有人对如何提高此代码的编译时安全性有任何进一步的建议,请发表评论!