Тема: Асинхронное программирование в Silverlight – исполнение в потоке UI
Асинхронное программирование в Silverlight – исполнение в потоке UI
Я разбирался с таймерами и веб-сервисами когда столкнулся с затруднением связанным с обращением к UI из фонового потока. Оказывается, такая операция запрещена. К данным UI разрешено обращаться только из потока UI. Давайте посмотрим, как вы можете обратиться к потоку UI из другого фонового потока.
Рассмотрим такую ситуацию:
Имеются какие-то данные, которые нужно модифицировать с интервалом в одну минуту. Данные загружаются веб-сервисом.
Операцию изменения вы можете производить, используя класс Timer. Вызовы таймера и веб-сервиса происходят асинхронно.
1: ...
2: Timer t = new Timer( GetData, null, TimeSpan.Zero, new TimeSpan( 0, 1, 0 ) );
3: ...
4:
5: public void GetData( object stateInfo )
6: {
7: SampleWebServiceSoapClient client = new SampleWebServiceSoapClient();
8: client.HelloWorldCompleted +=
9: new EventHandler<HelloWorldCompletedEventArgs>( client_HelloWorldCompleted );
10: client.HelloWorldAsync();
11: }
12:
13: private void client_HelloWorldCompleted( object sender, HelloWorldCompletedEventArgs e )
14: {
15: // update the UI
16: }
К сожалению, этот код не будет работать. Если вы попытаетесь обратиться к UI в функции обратного вызова, будет выброшено исключение: «Invalid cross-thread access».
Итак, что же мы можем сделать, чтобы данный код работал? Как минимум есть два пути:
1. Для обращения к потоку UI использовать класс Dispatcher.
2. Вместо System.Threading.Timer воспользоваться System.Windows.Threading.DispatcherTimer