Comments 14
Очень забавно все это писать, если у нас имеется много различных контролов, которые нужно изменять из разных потоков.
И если вы сделаете в обычном приложении
Thread thr=new Thread(Foo);
thr.Start();
где метод Foo изменяет какой либо контрол, появится исключение
Cross-thread operation not valid: Control 'labelControl1' accessed from a thread other than the thread it was created on
И если вы сделаете в обычном приложении
Thread thr=new Thread(Foo);
thr.Start();
где метод Foo изменяет какой либо контрол, появится исключение
Cross-thread operation not valid: Control 'labelControl1' accessed from a thread other than the thread it was created on
У контролов специально для этого есть BeginInvoke, который эту проблему решает.
А вообще… если у вас много разных потоков и из каждого вы меняете свойства разных котролов – значит вы не умеете проектировать.
А вообще… если у вас много разных потоков и из каждого вы меняете свойства разных котролов – значит вы не умеете проектировать.
Я знаю, что есть BeginInvoke и он мной используется в нужных местах.
А про проектирование разговора сейчас не идет.
А про проектирование разговора сейчас не идет.
Но в Compact Framework BeginInvoke не прокатывает.
Даж специально проверил сейчас – работает :)
Пример можно?
Я просто пробовал для потоков делать BeginInvoke() — оно говорило, что Compact Framework не поддерживает асинхронные потоки — как-то так.
Я просто пробовал для потоков делать BeginInvoke() — оно говорило, что Compact Framework не поддерживает асинхронные потоки — как-то так.
к примеру, нужно сделать:
тогда можно сделать для краткости вот так:
а вот тут есть замечательный класс DelegateInvoker, который я (иногда с некоторыми модификациями) уже давно успешно использую. По названию, я думаю, видно чем он занимается :)
textBox.Text = this.Text;
тогда можно сделать для краткости вот так:
public delegate void EmptyMethodHandler ();
...
textBox.BeginInvoke(new EmptyMethodHandler (delegate { textBox.Text = this.Text; }));
а вот тут есть замечательный класс DelegateInvoker, который я (иногда с некоторыми модификациями) уже давно успешно использую. По названию, я думаю, видно чем он занимается :)
Fixed
Потому что ThreadPool это вообще говоря просто набор заранее созданных потоков, которые ждут когда им чего-то передадут выполнять. Кажется у Рихтера в CLR via C# было написано, что потоки ThreadPool ничем не отличаются от обычных, для обычных хостов CLR (не уверен насчет SQL Server с его фибрами). Поэтому выполнение UI кода на ThreadPool потоках должно подчиняться тем же правилам, что и обычным Thread.
Это все, конечно, интересно, но, как мне кажется, вопрос выхода из потока более насущный
я лично использую к примеру textbox1.Invoke(new EventHandler(delegate { textbox1.Text = «Hello»; } ));
Можно сделать отельный метод, у меня это SynchronizedInvoke(Control target, MethodInvoker method), который перед вызовом проверяет InvokeRequired для target и вызывает либо target.Invoke(method), либо method() непосредственно. Для компонентов удобно использовать класс SynchronizationContext, это позволяет компонентам автоматически поддерживать модель синхронизации хоста (если она сделана через SynchronizationContext), а клиентам не обременять себя всякими Invoke (подробнее здесь). В частности, со второй версии .NET, эта модель поддерживается для WinForms.
Ссылка не вставилась — www.codeproject.com/KB/cpp/SyncContextTutorial.aspx.
Sign up to leave a comment.
Программирование потоков под Compact Framework