Простое, как грабли, через делегат:
string newText = "abc"; // running on worker thread this.Invoke((MethodInvoker)delegate { someLabel.Text = newText; // runs on UI thread });
То же самое, вынесено в отдельную функцию и выверено по MSDN:
delegate void UpdateLabelDelegate (string message); void UpdateLabel (string message) { if (InvokeRequired) { Invoke (new UpdateLabelDelegate (UpdateLabel), new object[] { message }); return; } MyLabelControl.Text = message; }
Там же - замечательные LINQ-оподобные конструкции, которые не так просто вставить в Blogger - там есть Template-овы конструкции вроде < Func <, а Blogger принимает их за теги. Поэтому не забываем ставить пробелы: Очаровательное LINQ-оподобное решение:
private delegate void SetPropertyThreadSafeDelegate(Control @this, Expression< Func > property, TResult value);
public static void SetPropertyThreadSafe(this Control @this, Expression< Func > 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(SetPropertyThreadSafe), new object[] { @this, property, value });
}
else
{
@this.GetType().InvokeMember(propertyInfo.Name, BindingFlags.SetProperty, null, @this, new object[] { value });
}
}
Улучшенные вариант с проверкой на null и более жёсткой типизацией:
public static void SetPropertyInGuiThread< C, V >(this C control, Expression< Func < C, V >> property, V value) where C : Control { var memberExpression = property.Body as MemberExpression; if (memberExpression == null) throw new ArgumentException("The 'property' expression must specify a property on the control."); var propertyInfo = memberExpression.Member as PropertyInfo; if (propertyInfo == null) throw new ArgumentException("The 'member' expression must specify a property on the control."); if (control.InvokeRequired) control.Invoke( (Action< C, Expression< Func < C, V >>, V>)SetPropertyInGuiThread, new object[] { control, property, value } ); else propertyInfo.SetValue(control, value, null); }
Комментариев нет:
Отправить комментарий