1. In. NET Framwork 2.0, the following code can be implemented:
1 2 3 4 5 6 7 8 9 10 11 12 |
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 }); } } |
The method is called as follows:
1 2 3 |
// thread-safe equivalent of // myLabel.Text = status; SetControlPropertyThreadSafe(myLabel, "Text" , status); |
2. In. NET 3.0 or later, you can override the above method as an extension method of a control class, which can simplify the invocation, with the following code:
1 |
myLabel.SetPropertyThreadSafe( "Text" , status); |
The complete invocation steps for versions above. NET 3.0 are as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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 || [email protected] 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 }); } } |
Make your code more concise by using LINQ and lambda expressions:
1 |
myLabel.SetPropertyThreadSafe(() => myLabel.Text, status); // status has to be a string or this will fail to compile |
3. The simplest anonymous method invocation:
1 2 3 4 5 6 |
///...blah blah updating files string newText = "abc" ; // running on worker thread this .Invoke((MethodInvoker) delegate { someLabel.Text = newText; // runs on UI thread }); ///...blah blah more updating files |
The above method collects from the network, only for the reference.
Reprint Please specify: The article is reproduced from: [169it-latest and most comprehensive it information]
Article title: C # Multithreaded Update window (WinForm) GUI data