Наверно, каждый человек, кто программирует под .NET Framework или Compact Framework, хоть раз в жизни сталкивался с потоками (Thread). И часто возникала проблема запуска функции с вызовом статического метода, в особенности это касается тех методов, где происходит изменение контролов формы. В этой статье я расскажу, как решить данную проблему.
Рассмотрим следующий пример. Есть какая-нибудь функция Foo():
Самый простой способ выполнения данной функции в потоке:
Теперь изменим нашу функцию таким образом:
В результате вылезет ошибка:
Это значит, что взаимодействие с контролом должно быть в отдельном потоке.
Еще один способ – использование пула потока и делегата:
Под Windows все нормально, а под Windows Mobile выскакивает та же ошибка.
Для решения данной проблемы нужно использовать метод Invoke для каждого контрола.
Создаем функцию изменения текста Label1:
Добавляем делегат для данной функции:
В функции Foo() изменяем строку
на:
Запускаем поток на выполнение:
Всё. Теперь при запуске программы на КПК или смартфоне вы увидите цифры от 1 до 100000.
Оригинал: forum.wce.by/viewtopic.php?f=15&t=14221&start=0
Рассмотрим следующий пример. Есть какая-нибудь функция 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