Довольно хорошо всем известна проблема возникающая при попытке обращения к свойствам или методам виндовс формы, 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());
Комментариев нет:
Отправить комментарий