Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> System.Threading.Timer, Проблема синхронизации 
V
    Опции темы
andrew_sh
Дата 4.3.2008, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Приветствую.  Столкнулся с "вечной" прблемой сихронизации таймера. Попробую описать суть.

WinControl используеться на странице *.aspx (в принципе не важно где). При его инициализации создается таймер (Threading.Timer). Который каждую секунду (для удобства) проверяет данные на диске и обновляет индикаторы на контроле. Если очень часто обновлять страницу (раз скажем 5-10, постоянно и даже не дожидаясь пока она обновиться до конца), а потом закрыть браузер, вываливается исключение.... Точно не помню..... Что то типа: ошибка синхронизации...вызывающего потока не существует

Т.е. тики таймера срабатывают и пытаються обновить контрол, которого уже нет.....  

Timer.Dispose() не помогает. Проверка Control.IsDisposed также не помогает. Пробовал через дополнительный обьект, также не катит... Даже не знаю куда копать и как с этим бороться.

ЗЫ: Примеры Кода и тект исключения приведу завтра утром (остались на работе).
PM MAIL   Вверх
andrew_sh
Дата 4.3.2008, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Вот собственно текст исключения :

A first chance exception of type 'System.ComponentModel.InvalidAsynchronousStateException' occurred in System.Windows.Forms.dll
Additional information: An error occurred invoking the method.  The destination thread no longer exists.

Вкратце код:

Код

Class Launcher
{
         public override void Initialize()
        {
            base.Initialize();
            ........
            // Создается обьект в котором и стартует таймер(листинг ниже)
            bdiagnostics = new BDiagnostics(FilesList, this);
            //обьект состояния, пытаюсь использовать для синхронизации
            stateObj = new StateObjClass();
            bdiagnostics.StartAsyncTimer(stateObj);
            ........
         }        

        public void UpdateVisitStatus(long visitID, int percent)
        {
            if (!this.IsDisposed)
            {
                VisitItem VI = this.treeModel.GetVisitItem(visitID);
                if (VI != null)
                {
                    if (LauncherThread.IsAlive)
                        //после изменения этого поля срабатывает событие перерисовки инддикаторов, на котором и слетает исключение
                        VI.BufferingIndicatorValue = percent;
                }
            }
        }
}




Класс BDiagnostic:

Код


        public void StartAsyncTimer(StateObjClass stateObj)
        {            
            stateObj = new StateObjClass();
            stateObj.TimerRef = dxTimer;
            stateObj.Canceled = false;
            dxTimer = new Timer(dxTimer_Tick, stateObj, 0, dxTimerInterval);
        }

        void dxTimer_Tick(object sender)
        {
            StateObjClass stateObj = (StateObjClass) sender;
                if (stateObj.Canceled)
                {
                    return;
                }
            lock (filesInVisit)
            {
                checkDownloadedFiles(stateObj);
            }
        }

        private void checkDownloadedFiles(StateObjClass stateObj)
        {
            bool allFilesDownloaded = false;
            long allDownloadedFilesCount = 0;
            foreach (KeyValuePair<int, FilesForVisit> pair in filesInVisit)
            {
                FilesForVisit thisFilesForVisit;
                if (filesInVisit.TryGetValue(pair.Key, out thisFilesForVisit))
                {
                    allFilesDownloaded = (thisFilesForVisit.CountInPercent() >= 100);
                    if (!allFilesDownloaded)
                    {
                        thisFilesForVisit.CheckDownloadedFiles();
                        lock (stateObj)
                        {
                            if (! stateObj.Canceled && !Launcher.IsDisposed)
                                 // вызов метода контрола, описанного в предыдщем листинге, который генерирет исключение
                                 dxLauncher.UpdateVisitStatus(pair.Key, thisFilesForVisit.CountInPercent());
                        }
                    }
                    else
                    {
                        allDownloadedFilesCount += thisFilesForVisit.CountDownloadedFiles;
                    }
                }
            }
            if (allDownloadedFilesCount == filesInVisit.Count)
                this.StopAsyncTimer(stateObj);
        }

        public void StopAsyncTimer(StateObjClass stateObj)
        {
            lock (stateObj)
            {
                stateObj.Canceled = true;
            }
            dxTimer.Dispose();
            dxTimer = null;
        }





Но вот собственно все.... Помогите разобраться плиз.....Уже 2 дня парюсь немлгу найти решение.... 

ЗЫ: За кривой код не бить, я еще только учусь )))
PM MAIL   Вверх
andrew_sh
Дата 4.3.2008, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Все разобрался ... 

В методе Dispose контрола сначала делал Dispose всем компонертем, а потом останавливал таймер, что и приводило к обращению несуществющих методов (вышеописаное исключение)....

Правильный код (читай рабочий)

Код

        protected override void Dispose(bool disposing)
        {
            // раньше вызывал в конце этого метода
            if (bdiagnostics != null && stateObj != null)
            {

                bdiagnostics.StopAsyncTimer(stateObj);
            }

            if (disposing && (components != null))
            {        
                components.Dispose();
            }
            base.Dispose(disposing);
        }




PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0746 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.