Диагностика Win32Exception «Quota Exceeded»

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

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

  • Сервер Win2008
  • 64-битная среда
  • Приложение WPF, используемое несколькими клиентами одновременно
  • Приложение — запуска, который открывает другие приложения с помощью Process.Start()
  • Иногда мы получаем исключение, указанное ниже
System.ComponentModel.Win32Exception (0x80004005): Недостаточно квоты
доступен для обработки этой команды
в MS.Win32.UnsafeNativeMethods.PostMessage(HandleRef hwnd,
WindowMessage msg, IntPtr wparam, IntPtr lparam)
в System.Windows.Interop.HwndTarget.UpdateWindowSettings(логическое
enableRenderTarget, Nullable`1 ChannelSet)
в System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
в System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg,
IntPtr wparam, IntPtr lparam)
в System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd,
Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& обработано)
в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam,
логическое значение& обработано)
в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(делегат
обратный вызов, аргументы объекта, Int32 numArgs)
в MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object
источник, метод делегата, аргументы объекта, Int32 numArgs, делегат
поймать обработчик)

РЕДАКТИРОВАТЬ #1 После некоторой проверки, вот более подробная информация:

  • Запуск — это двухэтапный процесс, пусковая установка запускает промежуточный процесс. Окно с помощью Process.WaitForExit()

  • Из промежуточного окна дальнейшие процессы могут быть запущены таким же образом (Process.WaitForExit).

  • При открытом только промежуточном окне и отсутствии взаимодействия с пользователем количество дескрипторов процесса запуска со временем увеличивается. Максимальное увеличение, которое мы видели здесь, составляет 400 --> 6000 дескрипторов.

Факты, добавленные в Edit, действительно заставляют меня задуматься, не может ли где-то быть утечка дескриптора во фреймворке. Я пытаюсь изолировать проблему и проверить, могу ли я воспроизвести ее с нуля. А пока с радостью принимается любая подсказка, идея, поддержка или даже шоколад!

РЕДАКТИРОВАТЬ #2: в попытке сделать процесс реагирующим на PostMessage()мы удалили Thread.WaitForExit. Вместо этого мы добавили обработчик для события Exited процесса и отправили Launcher в цикл, подобный следующему:

       while (foo == true)
        {
            System.Threading.Thread.Sleep(1000);
        }

Exited-Handler устанавливает fooв false и больше ничего не делает. Тем не менее, количество Handles растет (от 400 до 800 за полчаса).

РЕДАКТИРОВАТЬ #3 Вот, наконец, что-то интересное.

       while (foo == true)
        {
            System.Threading.Thread.Sleep(1000);
            GC.Collect();
        }

Это держит его таким, каким он должен быть, несколько ручек, все изящно. Теперь это заставляет меня задаться вопросом, что здесь не так ... Я снова поговорю с ответственным разработчиком, чтобы проверить, что еще делает программа запуска. До сих пор я слышал, что он считывает несколько значений конфигурации, используя XmlDocument.Load(), который не является IDisposable— что затрудняет создание какой-либо утечки здесь. ..

6
задан Sebastian Edelmeier 12 April 2012 в 09:58
поделиться