Довольно хорошо всем известна проблема возникающая при попытке обращения к свойствам или методам виндовс формы, WPF формы. Также известно что эта проблема решается с помощью применения маршализацыи.
Пример кода для работы с виндовс формой из фонового потока:
1: Action action = delegate()
2: {3: // код работы с формой и её контролами
4: label1.Text = 5: DateTime.Now.ToLongTimeString(); 6: };7: // проверка нужно ли исполнять код с помощью маршализации или нет,
8: //есле нужно применяем маршализацыю.
9: if (this.InvokeRequired)
10: this.Invoke(action);
11: else
12: action();Аналогичный пример для WPF:
1: Action action = () => textBlock1.Text = 2: DateTime.Now.ToString();3: if (System.Threading.Thread.CurrentThread !=
4: textBlock1.Dispatcher.Thread) 5: { 6: textBlock1.Dispatcher.Invoke 7: (System.Windows.Threading.DispatcherPriority.Normal, 8: action); 9: }10: else
11: { 12: action(); 13: }Данные примеры, вполне неплохо, подходят если вы используете возможность обращения к форма не очень часто, но в противном случае постоянное копирование кода начинает раздражать и усложнять код. По этому я предлагаю вам рассмотреть более элегантный метод применения морализации к любому контролу.
Метод расширения для класса Control для роботы из фонового потока.
1: public static class ControlExtensions
2: {3: public static void InvokeIfNeeded(this Control ctl,
4: Action doit) 5: {6: if (ctl.InvokeRequired)
7: ctl.Invoke(doit);8: else
9: doit(); 10: } 11: 12: public static void InvokeIfNeeded<T>(this Control ctl,
13: Action<T> doit, T args) 14: {15: if (ctl.InvokeRequired)
16: ctl.Invoke(doit, args);17: else
18: doit(args); 19: } 20: }Метод расширения контрола для работы из фонового потока совместимый с C# 2.0
1: public delegate void Action;
2: public delegate void Action<T>(T arg);
3: 4: public static class ControlExtensions
5: {6: public static void InvokeIfNeeded(Control ctl, Action doit)
7: {8: if (ctl.InvokeRequired)
9: ctl.Invoke(doit);10: else
11: doit(); 12: } 13: 14: public static void InvokeIfNeeded<T>( Control ctl,
15: Action<T> doit, T args) 16: {17: if (ctl.InvokeRequired)
18: ctl.Invoke(doit, args);19: else
20: doit(args); 21: } 22: }Пример использования
С# 2.0
1: private void OnTick20(object sender, EventArgs e)
2: {3: ControlExtensions.InvokeIfNeeded(this, delegate()
4: { 5: toolStripStatusLabel1.Text = 6: DateTime.Now.ToLongTimeString(); 7: }); 8: }С# 3.5
1: this.InvokeIfNeeded(() => toolStripStatusLabel1.Text =
2: DateTime.Now.ToLongTimeString());
Комментариев нет:
Отправить комментарий