Pull to refresh

Программирование потоков под Compact Framework

Reading time2 min
Views2.2K
Наверно, каждый человек, кто программирует под .NET Framework или Compact Framework, хоть раз в жизни сталкивался с потоками (Thread). И часто возникала проблема запуска функции с вызовом статического метода, в особенности это касается тех методов, где происходит изменение контролов формы. В этой статье я расскажу, как решить данную проблему.

Рассмотрим следующий пример. Есть какая-нибудь функция Foo():
int a=0;
void Foo()
{
  for(int i=0;i<100000;i++)
  {
   a++;
  }
  MessageBox.Show(a.ToString());
}


* This source code was highlighted with Source Code Highlighter.

Самый простой способ выполнения данной функции в потоке:
using System.Threading;

  Thread thr=new Thread(Foo);
  thr.Start();


* This source code was highlighted with Source Code Highlighter.

Теперь изменим нашу функцию таким образом:
int a=0;
void Foo()
{
  for(int i=0;i<100000;i++)
  {
   a++;
   label1.Text=a.ToString();
  }
}

* This source code was highlighted with Source Code Highlighter.

В результате вылезет ошибка:
SmartDeviceProject1.exe
NotSupportedException
Control.Invoke must be used to interact with controls created on a separate thread.

at System.Windows.Forms.Control.get_Text()
at System.Windows.Forms.Control.set_Text(String value)
at SmartDeviceProject.Form1.Foo()

Это значит, что взаимодействие с контролом должно быть в отдельном потоке.
Еще один способ – использование пула потока и делегата:
ThreadPool.QueueUserWorkItem( delegate { Foo(); });

* This source code was highlighted with Source Code Highlighter.

Под Windows все нормально, а под Windows Mobile выскакивает та же ошибка.
Для решения данной проблемы нужно использовать метод Invoke для каждого контрола.
Создаем функцию изменения текста Label1:
void ChangeLabel1Text(string text)
{
  label1.Text = text;
}


* This source code was highlighted with Source Code Highlighter.

Добавляем делегат для данной функции:
delegate void ChangeLabel1TextDelegate(string text);
ChangeLabel1TextDelegate cltd;
cltd = new ChangeLabel1TextDelegate (ChangeLabel1Text);


* This source code was highlighted with Source Code Highlighter.

В функции Foo() изменяем строку
label1. Text = a.ToString ();

* This source code was highlighted with Source Code Highlighter.

на:
label1.Invoke(cltd, a.ToString());

* This source code was highlighted with Source Code Highlighter.

Запускаем поток на выполнение:
ThreadPool .QueueUserWorkItem( delegate { Foo(); });

* This source code was highlighted with Source Code Highlighter.


Всё. Теперь при запуске программы на КПК или смартфоне вы увидите цифры от 1 до 100000.

Оригинал: forum.wce.by/viewtopic.php?f=15&t=14221&start=0
Tags:
Hubs:
+6
Comments14

Articles