Отчего база не начинает свое создание?
От: AlexNek  
Дата: 24.08.11 23:36
Оценка:
В Janus.cs есть код


                               if (DBSchemaManager.IsNeedRestructuring(host))
                                {
                                    ProgressWorker.Run(rootManager, false,
                                        progressVisualizer =>
                                        {
                                            progressVisualizer.SetProgressText(SR.Splash.RestructureDatabase);
                                            try
                                            {
                                                DBSchemaManager.Restruct(host);
                                                DatabaseManager.ClearTopicInfo(host);
                                                Config.Instance.BadRestruct = false;
                                            }
                                            catch
                                            {
                                                Config.Instance.BadRestruct = true;
                                                Config.Save();
                                                throw;
                                            }
                                        }
                                }

Однако стартует он только после исключения в методе
 DatabaseManager.CheckTopicInfoIntegrity(host);
следующим за данным вызовом.

Прогресс становится видимым только после исключения ну и точка останова на Config.Instance.BadRestruct = false; срабатывает соответственно позже

Как бороться?
avalon 1.0rc3 rev 419, zlib 1.2.3
Re: Отчего база не начинает свое создание?
От: Буравчик Россия  
Дата: 25.08.11 05:14
Оценка: 6 (1)
Здравствуйте, AlexNek, Вы писали:

AN>Как бороться?


ProgressWorker.Run — асинхронный метод. Он вызывается параллельно с основным потоком.

В данном коде подразумевается, что будет выполнена реструктуризация, а затем основной поток продолжит выполнение. А на самом деле поток реструктуризации и основной поток работают одновременно. Кто-кого из этих потоков обгонит — не известно.

Вариантов несколько.
Первый — убрать асинхронность (ProgressWorker.Run), т.е. пустить синхронизацию в основном потоке.
Второй — синхронизировать два потока между собой. Я приводил код в [url=http://rsdn.ru/Forum/Message.aspx?mid=4282418&only=1]Re: Ошибки первого запуска
Автор: Буравчик
Дата: 24.05.11
[/url]. Этот же код сейчас в репозитории Януса.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Best regards, Буравчик
Re[2]: Отчего база не начинает свое создание?
От: AlexNek  
Дата: 26.08.11 11:22
Оценка: +1
Здравствуйте, Буравчик, Вы писали:

Б> AN>Как бороться?


Б> ProgressWorker.Run — асинхронный метод. Он вызывается параллельно с основным потоком.

Я так тоже думал.

Б> В данном коде подразумевается, что будет выполнена реструктуризация, а затем основной поток продолжит выполнение. А на самом деле поток реструктуризации и основной поток работают одновременно. Кто-кого из этих потоков обгонит — не известно.

Фигово только когда реструктуризации медленней.

Б> Вариантов несколько.

Б> Первый — убрать асинхронность (ProgressWorker.Run), т.е. пустить синхронизацию в основном потоке.
UI не понравится.
Б> Второй — синхронизировать два потока между собой. Я приводил код в [url=http://rsdn.ru/Forum/Message.aspx?mid=4282418&amp;only=1]Re: Ошибки первого запуска
Автор: Буравчик
Дата: 24.05.11
[/url]. Этот же код сейчас в репозитории Януса.

По моему, я понял отличия, я делал только WaitOne без DoEvents(), а без этого ProgressWorker.Run видимо не работает.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[2]: Отчего база не начинает свое создание?
От: AlexNek  
Дата: 27.08.11 19:18
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б> Второй — синхронизировать два потока между собой. Я приводил код в [url=http://rsdn.ru/Forum/Message.aspx?mid=4282418&amp;only=1]Re: Ошибки первого запуска
Автор: Буравчик
Дата: 24.05.11
[/url]. Этот же код сейчас в репозитории Януса.

Проверено, данный подход не рабочий. Как только Application.DoEvents() появляется до Application.Run возникают разные бяки.
Для теста можно вставить строку
Application.DoEvents();

в Janus.Main
перед
DatabaseManager.CheckTopicInfoIntegrity(host);

Сразу перестает работать синхронизация и трей иконка не работает правильно (исчезают контекстное меню и реакция на двойной щелчек). Наверняка есть еще что то.
Я все еще в процессе правки, пришлось инициализацию приложения полностью переделать.
avalon 1.0rc3 rev 419, zlib 1.2.3
Re[3]: Отчего база не начинает свое создание?
От: Буравчик Россия  
Дата: 28.08.11 00:09
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Проверено, данный подход не рабочий. Как только Application.DoEvents() появляется до Application.Run возникают разные бяки.


Не совсем так. Application.DoEvents перед Application.Run сам по себе не опасен. Я предполагаю, дело немного в другом, хотя и связано с DoEvents.

При запуске приложения
— В конструкции "using (var host = new JanusHost(rootManager))" производится поиск в сборках всех частей приложения (классов, помеченных атрибутом ActivePart) и их конструирование (вызывается конструктор). Каждая такая часть может публиковать сервисы необходимые для работы приложения. Также эти части могут обращаться к уже опубликованным сервисам.
— Далее, при выходе из конструкции "using (host.InitScope)" производится активирование всех частей приложения (вызов ActivatePart или т.п.).
— Далее, Application.Run

Проблем в следующем. Некоторые части приложения обращаются к GUI через асинхронные операции. Эти операции не выполняются сразу, а помещаются в очередь сообщений GUI для дальнейшей обработки.

Если мы выполняем все в том порядке как написано выше, то все ок: происходит создание частей, затем активирование всех частей, затем обработка сообщений которые насоздавали части в плане GUI (в Application.Run). Причем эти операции GUI выполняются в окружении, когда все части (сервисы) приложения уже работают.

Если мы вставляем DoEvents как в предложеном варианте, то мы запускаем некоторые операции GUI (в DoEvents), которые к этому времени насоздавали части приложения. При этом еще не были сформированы и активированы все сервисы приложения. В связи с этим и возникают такие проблемы.

Для подтверждения вышесказанных слов достаточно поставить DoEvents сразу после блока "using (host.InitScope)", тем самым гарантируя, что этот DoEvents будет выполнен уже после активирования всех частей приложения. В этом случае ошибок не возникает.

Варианты решения:
1. Вынести работу по проверке и созданию БД из блока using. После этого блока можно безболезненно использовать DoEvents.
2. В принципе, можно попытаться разобраться чем отличается окружение (опубликованные сервисы) при первом и последующем запуске, и исправить проблемы в сервисах, но, это трудоемко.

Вообще, описанный подход к запуску приложения, на мой взгляд, слишком сложен. Более правильный вариант был бы, если бы части приложения при запуске приложения различали бы фазы "до GUI" и "GUI". Или даже вообще всю работу выполняли когда очередь сообщений уже запущена, т.е. после Application.Run.

AN>Сразу перестает работать синхронизация и трей иконка не работает правильно (исчезают контекстное меню и реакция на двойной щелчек). Наверняка есть еще что то.


Синхронизация работает нормально после первого запуска.
С контекстным меню у иконки в трее, действительно, есть проблема.

AN>Я все еще в процессе правки, пришлось инициализацию приложения полностью переделать.


Это правильно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Best regards, Буравчик
Re[4]: Отчего база не начинает свое создание?
От: AlexNek  
Дата: 28.08.11 09:59
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, AlexNek, Вы писали:


AN>>Проверено, данный подход не рабочий. Как только Application.DoEvents() появляется до Application.Run возникают разные бяки.


Б>Не совсем так. Application.DoEvents перед Application.Run сам по себе не опасен. Я предполагаю, дело немного в другом, хотя и связано с DoEvents.

думаю, что предположение правильное, я этого просто не знал. Краду твой текст для документации.

Б>Вообще, описанный подход к запуску приложения, на мой взгляд, слишком сложен. Более правильный вариант был бы, если бы части приложения при запуске приложения различали бы фазы "до GUI" и "GUI". Или даже вообще всю работу выполняли когда очередь сообщений уже запущена,

Б>т.е. после
входа в
Б>Application.Run.
Я сделал по другому. "Создал еще один Application.Run" и там делаю весь апдейт базы. Иначе говоря, разделил инициализацию на ГВИ и не ГВИ части.
Можно тута глянуть, может чего напортачил. Там два новых класса InvisibleInitializationForm и JanusApplicationContext


AN>>Сразу перестает работать синхронизация и трей иконка не работает правильно (исчезают контекстное меню и реакция на двойной щелчек). Наверняка есть еще что то.


Б>Синхронизация работает нормально после первого запуска.

Попробуй Application.DoEvents вставить. У меня перестала работать.
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
Re[5]: Отчего база не начинает свое создание?
От: Буравчик Россия  
Дата: 28.08.11 17:44
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>думаю, что предположение правильное, я этого просто не знал. Краду твой текст для документации.


Я не против. Но будет лучше, если кто-нибудь (может AVK?) подтвердит, что написанное верно

AN>Я сделал по другому. "Создал еще один Application.Run" и там делаю весь апдейт базы. Иначе говоря, разделил инициализацию на ГВИ и не ГВИ части.

AN>Можно тута глянуть, может чего напортачил. Там два новых класса InvisibleInitializationForm и JanusApplicationContext

Посмотрю. Так или иначе, переделывать запуск когда-нибудь придется

Б>>Синхронизация работает нормально после первого запуска.

AN>Попробуй Application.DoEvents вставить. У меня перестала работать.

Пробовал — синхронизация работает. Хотя это и не важно, т.к. надо решать все в комплексе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Best regards, Буравчик
Re[6]: Отчего база не начинает свое создание?
От: AlexNek  
Дата: 28.08.11 20:06
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, AlexNek, Вы писали:


AN>>думаю, что предположение правильное, я этого просто не знал. Краду твой текст для документации.


Б>Я не против. Но будет лучше, если кто-нибудь (может AVK?) подтвердит, что написанное верно

Конечно, не помешает. Но мне кажется, что рассуждения резонные.

Б>>>Синхронизация работает нормально после первого запуска.

AN>>Попробуй Application.DoEvents вставить. У меня перестала работать.

Б>Пробовал — синхронизация работает. Хотя это и не важно, т.к. надо решать все в комплексе.

А у меня ошибки не появляются и бывало окно просто застывало. Но важно, что при данном подходе все же появляются проблемы.

Я пока буду потихоньку тестировать, что сделал, одну ошибку как раз нашел (при показе ошибок нельзя без огляки пользоваться сервисом UIShell, его может еще просто не быть.)
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R6 rev. 8461&gt;&gt;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.