Недопустимый доступ к нескольким потокам в фоновом агенте
Я создаю RSS Reader и хочу добавить периодическое задание, которое будет проверять наличие новых элементов ленты. Если он найдет какие-либо новые элементы, он соответствующим образом обновит Live Tile приложения.
Проблема, с которой я сталкиваюсь, заключается в том, что я использую метод DownloadStringAsync() для загрузки каналов и проверки, содержат ли они новые элементы. Таким образом, иногда процесс загрузки может занимать более 20 секунд (время, которое дается периодическому заданию для выполнения своих действий).
Все, что я хочу, это убедиться, что метод NotifyComplete() будет вызван до того, как агент завершит работу ОС, после 20 секунд действия. По этой причине я хочу зарегистрировать диспетчерский таймер с интервалом в 15 секунд, который вызовет метод NotifyComplete() в своем событии тика.
Однако я попытался объявить и использовать таймер диспетчера, и возникла ошибка недопустимого межпоточного доступа. Код моей периодической задачи включает в себя следующее:
public class ScheduledAgent : ScheduledTaskAgent
{
//Register a DispatcherTimer
DispatcherTimer masterTimer = new DispatcherTimer();
private static volatile bool _classInitialized;
public ScheduledAgent()
{
if (!_classInitialized)
{
_classInitialized = true;
// Subscribe to the managed exception handler
Deployment.Current.Dispatcher.BeginInvoke(delegate
{
Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
});
}
//Set Timer properties
masterTimer.Interval = TimeSpan.FromSeconds(15);
masterTimer.Tick += masterTimer_Tick;
}
protected override void OnInvoke(ScheduledTask task)
{
//TODO: Add code to perform your task in background
masterTimer.Start();
//Call DownloadStringAsync() and perform other tasks...
//Call NotifyComplete() after the download is complete.
//
}
private void masterTimer_Tick(object sender, EventArgs e)
{
masterTimer.Stop();
//There is no more time left, we must call NotifyComplete() so as to avoid
//having the periodic task terminated by the OS
NotifyComplete();
}
}
Вопрос в том, почему это происходит и как я могу решить проблему. Заранее спасибо!
1 ответ
Ошибка доступа к многопоточному потоку возникает при попытке изменения свойства пользовательского интерфейса из потока, отличного от того, который создал элемент управления.
Чтобы передать его, вы используете метод Invoke, который существует в элементе управления
код должен выглядеть примерно так:
Control.Invoke((MethodInvoker)delegate{
//Do your work here for example NotifyComplete();
});