Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
ADOMD.NET 9.0: XmlaReader.Close() зависает с AS2000
|
|||
|---|---|---|---|
|
#18+
Задача: прервать выполнение AdomdCommand.ExecuteXmlReader(). Последовательность действий: В одном потоке делаю AdomdCommand.ExecuteXmlReader(), потом в цикле читаю этот ридер, за 10 секунд после него другой поток обрывает первый (Thread.Abort). Попадаем в finally, где вызывается reader.Close(), который работает очень долго - в этом и проблема. Обнаружено: Начал копать на чем зависает reader.Close(), и вижу последовательность: XmlaReader.Close(), XmlaReader.ReturnReader(), XmlaClient.EndReceival(), IXMLAStream.Skip(), ну а в нем вот это: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. Вопросы: 1) Зачем нам делать вычитывание всего этого ненужного контента в цикле while? Ведь readStream потом все-равно закроют, и все, что оттуда вычитали, никем не будет использовано. 2) Можно ли безболезненно удалить этот (на первый взгляд) ненужный цикл? Или существует способ получше для того, чтобы прервать AdomdCommand.ExecuteXmlReader()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.05.2006, 19:57 |
|
||
|
ADOMD.NET 9.0: XmlaReader.Close() зависает с AS2000
|
|||
|---|---|---|---|
|
#18+
Пример крупной утечки памяти с ADOMD.NET 8.0. AS2000, база FoodMart 2000. В цикле запускаем поток, ждем 5 секунд, abort-аем поток. В потоке устанавливаем коннект, открываем ридер, начинаем читать, и если оборвали - не закрываем ридер, так как будет КОНКРЕТНЫЙ тормоз (почему - см. выше). Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. И наблюдаем вот такую картину: 0) если поток обрывается на момент выполнения XmlaReader.Read(), то срабатывает XmlaReader.HandleException который успешно сделает XmlaClient.Disconnect(endsession=false). Тот в свою очередь вызовет CloseAll, дальше IXmlaStream.Dispose(), ну а тот закроет все стримы построенные на COM (NativeIStream и пр.). Проблема: память при этом ДАЖЕ НЕ ДУМАЕТ освобождаться. 1) если поток обрывается на момент выполнения действия после Read (в демонстрационном коде - Thread.Sleep(68)), то connection.Close() вылетает с грохотом "The connection cannot be used while an XMLReader object is open". А почему? А потому в отличие от предыдущего случае идет вызов XmlaClient.Disconnect(endsession=true) -> XmlaClient.EndSession, который естественно отваливается ибо ридер еще открыт. 2) AdomdCommand.Cancel, вызваннае как перед Thread.Abort, так и внутри, не помогает - матерится "the session sddsf384932jdsdasff does not exist" если поток обрывается на момент XmlaReader.Read. А в чем же задача? В том, чтобы в реальной апликации оборвать выполнение запроса, когда пользователь нажал на кнопку Cancel. Так вот, если обрывать поток, то память не освобождается. Даже несмотря на то, что теоретически все закрыто. Если запустить вышеуказанный пример, то можно наблюдать как размер памяти, занимаемой процессом, все пухнет, пухнет, пухнет, пока не зажрет все и не вылетит "you are out of virtual memory". .NET Memory Profiler показывает, что проблема как раз в native memory. Похоже на то, что если не выкачать из ридера все то, что пользователю 100 лет не нужно (ибо он нажал Cancel), то даже несмотря на все вызовы Marshal.ReleaseComObject(this.nativeIStream) native memory не освобождается, и все тут. Короче, люди добрые, у меня полный стопор. Надо оборвать выполнение команды, да так, чтобы вся память ОСВОБОДИЛАСЬ, и чтобы сам процесс обрыва ПРОХОДИЛ МГНОВЕННО. Буду очень благодарен за любые советы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2006, 01:06 |
|
||
|
ADOMD.NET 9.0: XmlaReader.Close() зависает с AS2000
|
|||
|---|---|---|---|
|
#18+
Вы какой XMLA провайдер используете? IXMLA? Тот что в вашем же процессе живет? Исходя из собственного опыта - бросте вы эту идею - аккуратно освобождать память. Я бился над этой затеей не одну неделю. Ничего путнего не вышло. BobakNET Memory Profiler показывает, что проблема как раз в native memory. Похоже на то, что если не выкачать из ридера все то, что пользователю 100 лет не нужно (ибо он нажал Cancel), то даже несмотря на все вызовы Marshal.ReleaseComObject(this.nativeIStream) native memory не освобождается, и все тут. Так оно и было. Запрос выполняется на стороне клиента, в адресном вашего процесса. То что вы со сторны .Net обрубили все концы для PTS ничего не значит - он продолжает выполнять запрос и заполнять ячейки. А то что вы их не читаете - это не его проблема. Он крутся дальше. Единственная рекомендация - держать IXMLA в отдельном процессе, и если надо обрубить запрос, надо убивать этот процесс. Но и это не факт что поможет - в зависимости от характера MDX запроса сам AS2000 может дальше выполнять этот запрос и ему будет начхать на то, что PTS клиент ушел в небытие. Это же Shilon - C'est la vie. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2006, 01:39 |
|
||
|
ADOMD.NET 9.0: XmlaReader.Close() зависает с AS2000
|
|||
|---|---|---|---|
|
#18+
backfireВы какой XMLA провайдер используете? IXMLA? Тот что в вашем же процессе живет? так и есть. backfireИсходя из собственного опыта - бросте вы эту идею - аккуратно освобождать память. Я бился над этой затеей не одну неделю. Ничего путнего не вышло. И что посоветуете делать? Выносить в отдельный процесс? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2006, 01:55 |
|
||
|
|

start [/forum/topic.php?fid=49&fpage=328&tid=1870103]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
27ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
31ms |
get tp. blocked users: |
1ms |
| others: | 209ms |
| total: | 303ms |

| 0 / 0 |
