Сбой создания диспетчера текущего потока в новом потоке STA

У меня есть служба Windows, работающая под учетной записью Local System, которая анализирует документы XPS.

На одной машине создание диспетчера в потоке анализа всегда терпит неудачу, но на всех других машинах, которые мы пробовали, это работало без каких-либо проблем.

На неисправной машине работает Server 2012 R2 с .NET 4.7.2, я полагаю, что мы ранее тестировали этот код на этой ОС, и все работало, но я настраиваю виртуальную машину, чтобы подтвердить это сейчас.

Вот минимальная версия кода, который дает сбой:

var staThread = new Thread(() => {
    var _ = Dispatcher.CurrentDispatcher;

    // Code that does the analysis would be here but is never reached
});

staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();

И вот исключение:

System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this command
   at MS.Win32.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
   at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
   at System.Windows.Threading.Dispatcher..ctor()
   at System.Windows.Threading.Dispatcher.get_CurrentDispatcher()
   ... [name of the class/method with the above code omitted]

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

Как рекомендовано в этом потоке, я попытался посмотреть на дескрипторы, пользовательские объекты и объекты GDI в диспетчере задач, пока он работал, и дескрипторы были около 800, пользовательские объекты и объекты GDI были равны 0 до запуска кода, а затем он сразу же разбился (так что если какое-либо из этих значений изменилось, это было слишком быстро, чтобы увидеть до сбоя).

Любые идеи?


person Lawrence Johnston    schedule 27.06.2019    source источник
comment
Вы используете это как службу Windows, но пытаетесь открыть окно?   -  person Ron Beyer    schedule 27.06.2019
comment
У служб Windows не может быть пользовательского интерфейса, по крайней мере, это не рекомендуется, потому что у службы нет рабочего стола, на котором можно создать окно.   -  person RobertBaron    schedule 27.06.2019
comment
@RobertBaron, Ron Beyer, мы, конечно же, не открываем окно намеренно, как вы можете видеть в предоставленном коде, который нигде явно не делается. Мы пытаемся использовать, например, метод XpsDocument.GetFixedDocumentSequence () для анализа документа XPS, но мы даже не зашли так далеко.   -  person Lawrence Johnston    schedule 27.06.2019
comment
Есть ли причина, по которой создание диспетчера также создает окно?   -  person Lawrence Johnston    schedule 27.06.2019
comment
Что это за диспетчер? Мы не можем сказать по опубликованному коду.   -  person RobertBaron    schedule 27.06.2019
comment
Функциональному диспетчеру требуется окно, он создает его, если вы этого не сделали сами. Существует жесткий верхний предел общего количества окон, которые могут быть созданы всеми процессами, работающими на рабочем столе, 65 535 в сеансе, который взаимодействует с пользователем. Гораздо ниже для сеанса 0. Проблема, характерная только для одной машины, легко решается: вы просите кого-нибудь выбросить ее или переформатировать ее диск.   -  person Hans Passant    schedule 27.06.2019
comment
@RobertBaron Это System.Windows.Threading.Dispatcher.   -  person Lawrence Johnston    schedule 27.06.2019
comment
@HansPassant Спасибо за информацию. Может случиться так, что мы действительно нарушаем рекомендацию об использовании пользовательского интерфейса в службах Windows, просто используя методы XpsDocument, для которых требуется Dispatcher, хотя на самом деле мы не отображаем какой-либо пользовательский интерфейс для пользователя. Если мы определим, что это действительно проблема, то если бы мы переместили логику XPS в исполняемый файл командной строки и запустили ее из службы Windows с помощью System.Diagnostics.Process, предотвратит ли это проблему или она все равно будет работать в сеансе 0? (Я проведу небольшое исследование по этому поводу, но, может быть, вы знаете это навскидку.)   -  person Lawrence Johnston    schedule 27.06.2019
comment
См. stackoverflow.com/questions/3351531/. Это предоставит рабочий стол для службы Windows, но не рекомендуется MS.   -  person RobertBaron    schedule 27.06.2019