Как получить Текущее количество дескрипторов окон и Ограничение дескрипторов окон в .NET? - PullRequest
10 голосов
/ 27 сентября 2008

Я хочу получить текущее количество дескрипторов окон и общесистемный лимит дескрипторов окон в C #. Как мне это сделать?

Ответы [ 3 ]

16 голосов
/ 11 февраля 2009

Если вы прочитаете пост Раймонда Чена, вы, вероятно, найдете его таким же раздражающим, как и я. Вы только «вероятно делаете что-то неправильно», потому что вы делаете то, на что не способна Windows.

В моем приложении, когда пользователь впервые посещает вкладку, я создаю и размещаю все элементы управления на этой странице. Это занимает заметное количество времени - на странице может быть 50 элементов управления. Поэтому я не сбрасываю элементы управления на вкладке после ее заполнения, если это вообще возможно, и оставляю закрытые наборы вкладок на усмотрение пользователя.

Как это бывает, некоторые пользователи никогда не хотят закрывать любые наборы вкладок. Почему я должен заставлять их? Благодаря моему пользовательскому интерфейсу они могут очень быстро переходить к любому из 300+ наборов транзакций, которыми они управляют. Их машины достаточно быстрые и имеют достаточно памяти, чтобы все это было очень отзывчивым. Единственная проблема в том, что Windows не может это поддерживать.

Почему я использую элементы управления, а не какую-то другую технологию пользовательского интерфейса? Потому что они работают . Мне нужно поддерживать события фокуса, порядок табуляции, события проверки, динамическое расположение и привязку данных - пользователи фактически управляют тысячами записей в десятках таблиц в наборе данных в памяти. Степень развития, которую я должен был бы выполнить, скажем, для реализации чего-либо с использованием элементов управления без окон, астрономическая.

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

В любом случае, мое решение состоит из двух частей.

Во-первых, класс, который может сообщить вам, сколько обработчиков окна использует ваш процесс:

using System;
using System.Runtime.InteropServices;

namespace StreamWrite.Proceedings.Client
{
    public class HWndCounter
    {
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetCurrentProcess();

        [DllImport("user32.dll")]
        private static extern uint GetGuiResources(IntPtr hProcess, uint uiFlags);

        private enum ResourceType
        {
            Gdi = 0,
            User = 1
        }

        public static int GetWindowHandlesForCurrentProcess(IntPtr hWnd)
        {
            IntPtr processHandle = GetCurrentProcess();
            uint gdiObjects = GetGuiResources(processHandle, (uint)ResourceType.Gdi);
            uint userObjects = GetGuiResources(processHandle, (uint)ResourceType.User);

            return Convert.ToInt32(gdiObjects + userObjects);
        }
    }
}

Во-вторых, я поддерживаю кеш-объект, использованный на моей странице-вкладке реже всего недавно. .NET Framework не предоставляет универсальный класс кэша LRU, поэтому я создал один, который вы можете получить здесь , если он вам нужен. Каждый раз, когда пользователь посещает вкладку, я добавляю ее в LRU Cache. Затем я проверяю, не хватает ли мне оконных ручек. Если да, я выбрасываю элементы управления на вкладке с наименее недавно использованной вкладкой и продолжаю делать это до тех пор, пока у меня не будет достаточно оконных дескрипторов.

3 голосов
/ 27 сентября 2008

Как сказал Рэймонд Чен некоторое время назад, если вы думаете об ограничениях дескриптора окна, вы, вероятно, делаете что-то не так:)

Во всяком случае, держу пари, что нет специального C # способа сделать это, потому что это очень специфично для системы. Вы можете использовать те же функции, что и в приложении C ++. Вызовите функции, используя P / Invoke. Чтобы узнать, как написать импорт, перейдите на pinvoke.net .

Редактировать: Как я понимаю ваш вопрос, я предполагаю, что вы уже знаете, как это сделать в приложении Win32.

0 голосов
/ 27 сентября 2008

Полная цитата, на которую ссылается OregonGhost:

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

Это от Почему ограничение дескрипторов окон на процесс составляет 10 000? Вам следует прочитать это.

...