SheepSpeech Ответов: 2

Какова связь между насосом сообщений windows и исключением outofmemory?


Привет,

Я хотел бы понять проблему, с которой я в настоящее время сталкиваюсь.

Я создал приложение на языке C# с помощью Winforms. У меня есть длительная операция (несколько минут).
Когда я запустил эту операцию, чтобы проверить ее непосредственно в одном из моих элементов управления в графическом слое (скажем, "onButtonTestClicked ()"), окна были заморожены, как я и ожидал, и приложение росло и росло до 2 гигабайт в памяти (!), вызывая это исключение OutOfMemory.
Однако, когда я запустил свою длинную операцию в новом потоке из onButtonTestClicked(), он использовал только до 200 мегабайт.
Я подозреваю, что эта проблема связана с перекачкой сообщений Windows: когда приложение заморожено, оно не может перекачивать сообщения так, как должно. Но какова связь со всем этим занимаемым пространством памяти?

Не могли бы вы объяснить, почему? Мне это очень интересно.

Спасибо!

Что я уже пробовал:

Ну, в Интернете я почти ничего не нашел. Вот некоторые документы: О сообщениях и очередях сообщений (Windows)[^]

При отладке у меня появляется это сообщение об ошибке:
The CLR has been unable to transition from COM context 0x1a0b88 to COM context 0x1a0cf8 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

Dave Kreskowiak

Нет никаких отношений.

Не видя соответствующего кода, невозможно сказать вам, что вы делаете неправильно.

ZurdoDev

Я согласен с Дейвом. Скорее всего, происходит что-то еще.

SheepSpeech

Ну, я не могу дать вам код, потому что это проект, над которым я работаю с другими людьми. Но я могу сказать вам, что я использую Entity Framework, и длительная операция генерирует записи для базы данных.
В любом случае, единственное различие между обоими случаями-это создание нового потока.

Я добавил сообщение об ошибке, которое получаю, когда нахожусь в режиме отладки. Интересная часть-это "или использование памяти, постоянно накапливающееся с течением времени". Это, кажется, быть связаны в некотором роде...

У вас есть какие-нибудь идеи, пусть даже смутные? Это может помочь мне выяснить, что здесь уместно.

Richard MacCutchan

Единственный способ узнать это-отладить ваш код. Как было отмечено выше, невозможно сделать даже смутное предположение, поскольку мы понятия не имеем, что делает ваш код.

2 Ответов

Рейтинг:
1

johannesnestler

Не блокируйте графический интерфейс так долго - пользователи получат сообщение "приложение не отвечает" в режиме выпуска. Так что используйте нити. И ваша вторая проблема, похоже, связана с вашей отладкой - когда вы устанавливаете точку останова в критичной по времени функции (например, есть тайм-аут для SQL-доступа), вы увидите, что тайм-аут происходит.


Рейтинг:
0

Patrice T

Цитата:
Какова связь между насосом сообщений windows и исключением outofmemory?

Между ними нет никакой связи. Или отношение-это ваш код.
Ваше приложение останавливает насос сообщений-это вторичный эффект того, что ваше приложение занято выделением памяти, но, не видя вашего кода, трудно сказать наверняка.


SheepSpeech

Спасибо. Но тогда как вы объясните эту часть сообщения об ошибке: "или использование памяти постоянно накапливается с течением времени"? Как я уже сказал, Это, кажется, быть связаны в некотором роде...