Первичный ключ – GUID или автоинкремент? / Хабр

Что такое guid?

Глобально уникальный идентификатор, также известный как универсальный уникальный номер ссылки, или GUID, – это аббревиатура. При вычислении GUID технически представляет собой 128-битный уникальный номер ссылки, который не будет повторяться.

Компания Microsoft называет процесс создания отличительного изображения в документе Word созданием GUID (глобально уникального идентификатора). Во многих продуктах Microsoft идентификаторы GUID используются для идентификации интерфейсов, наборов реплик и других объектов.

Upd: почему вариант с генерацией guid ключа на стороне базы работает медленно


Когда Entity Framework выполняет вставку в таблицу с автоинкрементным ключем, SQL команды выглядит примерно следующим образом:

INSERT [dbo].[AutoIncrementIntKeyEntities]([Name], [Count]) VALUES (@0, @1)
SELECT [Id] FROM [dbo].[AutoIncrementIntKeyEntities] WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()

Более сложный вариант получается, если GUID находится на стороне сервера:

DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT [dbo].[GuidKeyDbNonSequentialEntities]([Name], [Count]) OUTPUT inserted.[Id] INTO @generated_keys VALUES (@name, @count)
SELECT t.[Id] FROM @generated_keys AS g JOIN [dbo].[GuidKeyDbNonSequentialEntities] AS t ON g.[Id] = t.[Id] WHERE @@ROWCOUNT > 0

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

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

Захват устройства

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

Когда выполнять захват Во-вторых, захват всегда должен выполняться перед созданием интерфейса. Во-вторых, DirectInput может уведомить вас в любое другое время об одном или нескольких нарушениях.

Захват устройства выполняет вызов IDirectInputDevice8::Acquire:

HRESULT IDirectInputDevice8::Acquire();

П РИМЕЧАНИЯ

Обратившись к документации DX SDK, вы увидите, что функции IDirectInputDevice8 возвращают стандартный код ошибки DIERR_INPUTLOST, сообщающий, что устройство необходимо захватить (поскольку доступ к нему был утрачен).

Когда вы закончите работу, необходимо отпустить устройство. Это работа функции IDirectInputDevice8::Unacquire:

HRESULT IDirectInputDevice8::Unacquire();

ВНИМАНИЕ!

Убедитесь, что завершив работу с устройством вы вызываете для него функцию Unacquire. Отсутствие этого вызова может привести к зависанию системы.

Как узнать guid приложения

Shell – это иллюстрация вызова диспетчера устройств Windows.

Раздел реестра HKEY_CLASSES_ROOTCLSID

Откройте диалоговое окно “Выполнить”, нажав клавиши Win R, затем введите regedit, чтобы запустить редактор реестра. Перейдите в раздел реестра HWHRT и найдите HKEACLASSES-ROOMTCLIDE, используя GUID_OFLSID.

Пример: нам нужен {GUID} «Панели управления — Control Panel», методом перебора значений находим нужный, смотрим наличие подраздела ShellFolder.

G UID должен быть извлечен и проверен. Щелкните правой кнопкой мыши значение с расширением tgreg в меню “Экспорт”.

Если в качестве текстового редактора вы используете блокнот, щелкните правой кнопкой мыши только что созданный файл реестра.

Выделив значение и вставив его в диалоговое окно “Выполнить” с помощью клавиш Ctrl C, нажмите на клавиатуре.

Как узнать guid через cmd

Выполните команду, которая создает файл отчета на диске C в cmd, войдя в систему от имени администратора.

Если все было сделано правильно, компонент Windows должен запуститься. Если вы решили работать с реестром Windows, удачи вам и соблюдайте осторожность. С вами был Иван Семин, создатель и автор IT-портала msconfig.ru.

Как узнать guid через powershell

Я могу предоставить вам сценарий, если вы хотите быстро получить информацию о GUID:

Опрос устройства

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

Это не должно удерживать нас от использования опроса, поскольку это сделает основной код более универсальным и совместимым почти со всеми устройствами. Не волнуйтесь, опрос устройства, которому он не нужен, совсем не трудоемкий. Со временем код станет более осмысленным.

Опрос устройства выполняется через IDirectInputDevice8::Poll:

HRESULT IDirectInputDevice8::Poll();

Получение guid устройства

Каждому устройству был присвоен GUID (глобальный уникальный идентификатор). Вы должны знать GUID устройства, чтобы использовать его. Это можно сделать для клавиатуры и мыши компьютера. В DirectInput они называются соответственно GUID_SysKeyboard и GUED-Mouse. Чтобы найти это устройство, необходимо сначала перечислить все остальные устройства.

П РИМЕЧАНИЯ

Перечисление (enumeration) — это процесс перебора элементов списка. В нашем случае элементы — это устройства ввода, такие как джойстики. Предположим, к вашей системе подключено пять джойстиков. В процессе перечисления DirectInput будет передавать вам информацию, относящуюся к каждому джойстику, по одному за раз, пока не будут перебраны все джойстики, или вы не решите остановиться.

Работой функции EnumDevices является IDirectInput8:

HRESULT IDirectInput8::EnumDevices(
     DWORD            dwDevType,  // тип искомых устройств
     LPDIENUMCALLBACK lpCallback, // функция обратного вызова для перечисления
     LPVOID           pvRef,      // указатель на пользовательский набор данных
     DWORD            dwFlags);   // флаги перечисления

П РИМЕЧАНИЯ

Чтобы использовать значения GUID_SysKeyboard и GUID_SysMouse вы должны определить константу INITGUID прежде всех других директив препроцессора или включить в проект библиотеку DXGuid.lib.

#define INITGUID

Вы должны определить INITGUID только один раз в вашем проекте (в одном файле с исходным кодом); если вы сделаете это несколько раз, то при компиляции возникнет ошибка.

Группа битовых полей, известная как параметр dwDevType, определяет тип устройства, которое будет перечислено. Для этого доступны такие распространенные устройства ввода, как джойстики и мыши.

:/>  PowerShell on-screen alerts and popup boxes: Add them to your scripts

Устройства, которые могут быть указаны в DirectInput, перечислены в таблице 3.3.


ЗначениеОписание

DI8DEVCLASS_ALLВсе устройства
DI8DEVCLASS_GAMECTRLВсе игровые контроллеры (джойстики)
DI8DEVCLASS_KEYBOARDВсе клавиатуры
DI8DEVCLASS_POINTERВсе указывающие устройства (мыши)
DI8DEVCLASS_DEVICEВсе устройства, не относящиеся к трем предыдущим типам
DI8DEVTYPE_MOUSEМыши и подобные им устройства, такие как трекболы
DI8DEVTYPE_KEYBOARDКлавиатуры и подобные им устройства
DI8DEVTYPE_JOYSTICKДжойстики и подобные им устройства, такие как рули
DI8DEVTYPE_DEVICEУстройства, которые не относятся к трем предыдущим типам
DI8DEVTYPEMOUSE_TOUCHPADСенсорные панели (подтип)
DI8DEVTYPEMOUSE_TRACKBALLТрекболы (подтип)

На функцию enum, которая будет вызываться всякий раз, когда будет обнаружено подходящее для системы устройство, указывает переменная lpCallback. Позже я дам ее краткое описание. В параметре pvRef вы указываете буфер, обычно структуру данных, содержащую информацию.

Последний набор флагов, dwFlags, инструктирует DirectInput о том, как продолжить перечисление устройств. Аргумент dwFlags может быть любым из значений, показанных в таблице 3.4.

Таблица 3.4. Флаги перечисления


ЗначениеОписание

DIEDFL_ALLDEVICESПеречисляем все установленные устройства (значение по умолчанию)
DIEDFL_ATTACHEDONLYПеречисляем только подключенные устройства
DIEDFL_FORCEFEEDBACKПеречисляем только устройства с обратной связью
DIEDFL_INCLUDEALIASESВключаем устройства, которые являются псевдонимами других устройств
DIEDFL_INCLUDEPHANTOMSВключаем фантомные устройства (заглушки)

Функция является функцией перечисления с типом DESUMDeviceProc, о чем свидетельствует закомментированный указатель на функцию lpCallback.

BOOL CALLBACK DIEnumDevicesProc(
     LPDIDEVICEINSTANCE lpddi,  // структура данных устройства
     LPVOID             pvRef); // задаваемый пользователем указатель

На структуру DIDEVICEINSTANCES, содержащую сведения об обнаруженном устройстве, указывает параметр lpddi. Она выглядит следующим образом:

typedef struct {
    DWORD dwSize;       // Размер структуры
    GUID  guidInstance; // GUID устройства
    GUID  guidProduct;  // Предоставляемый OEM GUID устройства
    DWORD dwDevType;    // Тип устройства
    TCHAR tszInstanceName[MAX_PATH]; // Название устройства
    TCHAR tszProductName[MAX_PATH];  // Название продукта
    GUID  guidFFDriver; // GUID драйвера обратной связи
    WORD  wUsagePage;   // Используемая страница для устройств HID
    WORD  wUsage;       // Используемый код для устройств HID
} DIDEVICEINSTANCE;

П РИМЕЧАНИЯ

При работе со структурой DIDEVICEINSTANCE вам потребуются только поля guidInstance, dwDevType и tszInstanceName. Поле guidInstance — это GUID, необходимый для инициализации устройства (это именно то, что мы ищем). Поле dwDevType — это тип устройства, перечисляемого в данный момент.
И, наконец, tszInstanceName — это текстовый буфер, который содержит имя устройства (такое, как «Joystick 1»), которое можно использовать, например, для формирования списка из которого пользователь будет выбирать устройство.

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

П РИМЕЧАНИЯ

Еще одно замечание о перечислении: в функции перечисления вы должны определить надо ли продолжать перечисление, или следует остановиться, для чего необходимо вернуть значение DIENUM_CONTINUE или DIENUM_STOP соответственно.
// Глобальный COM-объект DirectInput
IDirectInput8 *g_pDI;

// Прототипы функций
BOOL InitDIAndEnumAllDevices(HWND hWnd, HINSTANCE hInst);
BOOL CALLBACK EnumDevices(LPCDIDEVICEINSTANCE pdInst,
                          LPVOID pvRef);

BOOL InitDIAndEnumAllDevices(HWND hWnd, HINSTANCE hInst)
{
    if(FAILED(DirectInput8Create(hInst, DIRECTINPUT_VERSION,
                      IID_IDirectInput8, (void**)&g_pDI, NULL)))
        return FALSE;

    g_pDI->EnumDevices(DI8DEVCLASS_ALL, EnumDevices,
                      (LPVOID)hWnd, DIEDFL_ALLDEVICES);

    return TRUE;
}

BOOL CALLBACK EnumDevices(LPCDIDEVICEINSTANCE pdInst,
                          LPVOID pvRef)
{
    int Result;

    // Отображаем окно сообщений с именем найденного устройства
    Result = MessageBox((HWND)pvRef, pdInst->tszInstanceName,
                        "Device Found", MB_OKCANCEL);

    // Продолжаем перечисление, если нажата кнопка OK
    if(Result == IDOK)
        return DIENUM_CONTINUE;

    // Завершаем перечисление
    return DIENUM_STOP;
}

Просто вызовите функцию InitDIAndEnumAll Devices(), вставив фрагмент кода, который вы хотите увидеть.

П РИМЕЧАНИЯ

Предположим, вы хотите перечислить только джойстики, подключенные к системе. Просто замените строку g_pDI->EnumDevices на следующую:

g_pDI->EnumDevices(DI8DEVTYPE_JOYSTICK,
                   EnumDevices, (LPVOID)hWnd,
                   DIEDFL_ATTACHEDONLY);

Создание com-объекта устройства

Знание GUID устройства и адресной книги позволяет теперь создать COM-объект под названием idirectInputDevice8. Название этой процедуры – IDirectInput8:CreateDevice.

HRESULT IDirectInput8::CreateDevice(
    REFGUID rguid, // GUID создаваемого устройства жестко
                   // заданный или определенный при перечислении
    LPDIRECTINPUTDEVICE *lplpDirectInputDevice, // Указатель на
                                                // создаваемый объект
    LPUNKNOWN pUnkOuter); // NULL - не используется

Вот пример использования IDirectInput8::CreateDevice:

IDirectInputDevice8 *pDIDevice;
HRESULT hr = g_pDI->CreateDevice(DeviceGUID, &pDIDevice, NULL);

Элемент системы мыши с заранее определенным GUID:

IDirectInputDevice8 *pDIDevice;
HRESULT hr = pDI->CreateDevice(GUID_SysKeyboard, &pDIDevice, NULL);

П РИМЕЧАНИЯ

Тестирование

В проект внесены соответствующие соображения.

В таблице представлены результаты теста, который проводился в соответствии со следующим планом:

В таблице приведены результаты каждого запуска.

Хотя никаких результатов пока не видно, одно можно сказать наверняка:

Последний пункт заслуживает внимания. Что может замедлять работу при использовании нестабильных GUID? Скорее всего, в результате частого чтения диска и чтения “случайных” страниц. Последовательный GUID гарантирует, что страница всегда находится в памяти.

При непоследовательном индексе существует множество вставок в ошибочные места, и совершенно неизвестно, где будет правильный адрес. чтобы определить влияние случайных чтений на результаты теста? Мы искусственно ограничим пространство памяти сервера SyLServer до такой степени, что ни одна таблица в нем не поместится.

Грубые расчеты показывают, что размер таблицы не превышает 400 Мб при длине строки 4000 символов (8000) и 50 000 записей. Давайте запустим этот тест снова, ограничив допустимый объем памяти SLServer до 256 Мб.

Логично, что вставка из таблицы с неустойчивыми GUID будет занимать больше времени. На производительность вставки для последовательных GUID и автоинкремента это также не влияет.

Типы guid

В RFC 4122 определено 5 различных версий GUID. Например, код версии 4 имеет формат 2 xx- 3 XX – одно 5 значение n или 8; B – число 1 из 9 цифр N [1]. GUID различаются по формату в зависимости от цифры, но не N.

  • Версия 1: Дата-время и MAC-адрес – Эта версия генерируется с использованием текущего времени и MAC-адреса клиента. Это означает, что если у вас есть GUID версии 1, вы можете определить, когда он был создан, проверив значение временной метки.
  • Версия 2: DCE Security – Эта версия не определена в RFC 4122, поэтому она не должна генерироваться совместимыми генераторами. Он похож на GUID версии 1, за исключением того, что первые 4 байта временной метки заменяются на UID пользователя или POSIX GID, а старший байт тактовой последовательности заменяется на UID домена / POSIX GID.
  • Версия 3: хэш MD5 и пространство имен – этот GUID генерируется путем взятия пространства имен (например, полностью определенного доменного имени) и заданного имени, преобразования их в байты, объединения и выполнения хэша. После указания специальных битов, таких как версия и вариант, полученные байты преобразуются в шестнадцатеричную форму. Особенностью этой версии является то, что GUID, сгенерированные от одного и того же имени в одном и том же пространстве имен, будут идентичны, даже если они сгенерированы в разное время.
  • Версия 4: случайный – Этот тип GUID создается с использованием случайных чисел – из 128 бит в GUID 6 зарезервированы для специального использования (биты варианта версии), в результате чего получается 122 бита, которые могут быть заполнены случайным образом. В спецификации не указано, как должны генерироваться случайные числа – они могут быть любыми, от псевдослучайных до криптографически защищенных. Поэтому эти GUID, как и все другие GUID, должны использоваться только для идентификации, а не для обеспечения безопасности.
  • Версия 5: хэш SHA-1 и пространство имен – Эта версия идентична версии 3, за исключением того, что на этапе хэширования вместо MD5 используется SHA-1.
:/>  Первые шаги для пауэршельшиков / Хабр

Какие разделы реестра нужно искать

Установка специальных свойств

Теперь можно задать любые уникальные настройки для устройства, включая режимы оси, буферизацию и максимальные значения диапазона. Режим оси имеет два варианта: относительный и абсолютный. В абсолютном режиме сообщаются координаты центральной точки. Положительные числа сообщаются для позиций справа и ниже этой точки, а отрицательные – для позиций слева или выше этой точки.

Перемещение относительно последней фиксированной позиции обозначается относительными координатами. Предположим, что указатель мыши находился, например, на отметке 100. 40 и сместился на 5 единиц вправо? Необходимо использовать любые соответствующие относительные перемещения.

Вы можете контролировать объем буферизации данных (при необходимости). В результате вы можете читать информацию, которую передает вам устройство, в своем собственном темпе, не беспокоясь о том, что она будет потеряна. Для того чтобы работать с данными в буфере, вам нужен какой-то инструмент. Я не буду говорить о буферизации, поскольку предпочтительнее знать о состоянии устройства ввода.

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

Функциональность IDirectInputDevice8 используется для вставки юридически обязательных данных:

HRESULT IDirectInputDevice8::SetProperty(
    REFGUID         rguidProp, // GUID свойства
    LPCDIPROPHEADER pdiph);    // DIPROPHEADER содержащий данные
                               // об устанавливаемом свойстве

П РИМЕЧАНИЯ

За один раз может быть установлено только одно свойство. Если необходимо установить другое свойство, вызовите функцию еще раз.

Свойство для настройки диапазона значений, сообщаемых джойстиком или режимом оси, GUID, указанный в rguidProp. Свойства GUID перечислены в таблице 3.7.

Таблица 3.7. GUID свойств


REFGUIDОписание

DIPROP_AUTOCENTERУказывает, является ли устройство самоцентрируемым
DIPROP_AXISMODEЗадает обсуждавшийся ранее режим осей
DIPROP_BUFFERSIZEОпределяет размер входного буфера
DIPROP_CALIBRATIONMODEУказывает должен ли DirectInput получать от устройства калиброванные данные. По умолчанию все данные калиброваны
DIPROP_DEADZONEРазмер мертвой зоны, в которой не регистрируются изменения. Может изменяться от 0 (отсутствует) до 10000 (100 процентов)
DIPROP_RANGEУстанавливает минимальное и максимальное значение диапазона
DIPROP_SATURATIONЗначение, определяющее максимальный диапазон устройства. Может находиться в диапазоне от 0 до 10000. Например, значение 9500 означает, что устройство, такое как джойстик, отклоненное на 95 процентов заданного диапазона будет считаться полностью отклоненным

Следующие определения относятся к структуре DIPROPHEADER, используемой в вызове SetProperty:

typedef struct {
    DWORD dwSize;       // Размер объемлющей структуры
    DWORD dwHeaderSize; // Размер данной структуры
    DWORD dwObj;        // Параметр, который мы устанавливаем
    DWORD dwHow;        // Как мы устанавливаем значение
} DIPROPHEADER, *LPDIPROPHEADER

Размеры структуры указываются в байтах в полях dwSize и dwHeadersize. В зависимости от того, какое свойство мы задаем, параметр dwObj может принимать различные значения. Ось X и ось 1 компьютера обозначаются значениями DIJOFS_X и DDINOFS-C, соответственно.

Значение последнего параметра, dwHow, мы установим в DIP H_BOFSET. Что будет указано в текущем формате данных для данного объекта или его компонента, решает DirectX SDK. Поэтому DIOFS_X и DIOFS-I – это смещения значений, которые должны быть заданы в текущем формате данных.

Я покажу, как настроить свойства джойстика позже в этой главе.

Установка уровня кооперации

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

Уровень сотрудничества устройства устанавливается на следующем этапе, для чего используется следующая функция:

HRESULT IDirectInputDevice8::SetCooperativeLevel(
     HWND  hWnd,      // Дескриптор родительского окна
     DWORD dwFlags);  // Флаги, определяющие вид совместного доступа

Введите значение параметра SetCooperativeLevel для виджета hWnd. Введите в API dwFlags одно из перечисленных ниже приложений для получения доступа к устройству совместно с другими приложениями.

:/>  Выбор текстового редактора или «хочу все в одном» / Хабр

Таблица 3.6. Уровни кооперации IDirectInputDevice8


УровеньОписание

DISCL_NONEXCLUSIVEИспользование данного параметра позволяет нескольким приложениям совместно использовать одно устройство ввода не влияя друг на друга
DISCL_EXCLUSIVEЭтот параметр делает вашу программу захватчиком. При захвате устройства вы получаете единоличный доступ к нему, даже если другие установили эксклюзивный режим использования
DISCL_FOREGROUNDПриложению требуется доступ при активности. Это означает, что для использования устройства программа должна быть активной. Если ваша программа становится неактивной, устройство будет автоматически освобождено, и вам надо будет восстановить контроль, когда программа вновь получит фокус
DISCL_BACKGROUNDВашей программе требуется фоновый доступ. Это значит, что программа может обращаться к устройству, даже когда она неактивна
DISCL_NOWINKEYБлокирует клавишу с логотипом Windows

П РИМЕЧАНИЯ

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

Когда вы задаете уровень кооперации, то должны указать флаг DISCL_EXCLIUSIVE либо флаг NONEXCLASIVES и связать его со знаменем группы. Я рекомендую для рассматриваемых устройств комбинацию DISCL_FOREGROUND и NONEXCLAUSIVE:

pDIDevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

Установка формата данных

У каждого устройства есть собственный формат данных, используемый при чтении. В нем необходимо учесть множество вещей: клавиши, кнопки, оси и т.д. Чтобы ваша программа могла начать читать данные устройства, необходимо сообщить DirectInput этот формат.

Делается это через функцию IDirectInputDevice8::SetDataFormat:

HRESULT IDirectInputDevice8::SetDataFormat(LPCDIDATAFORMAT lpdf);

Структура DIDATAfORMAT является единственным аргументом функции SetDataFormat. Определение структуры выглядит следующим образом:

typedef struct {
    DWORD dwSize;     // Размер структуры
    DWORD dwObjSize;  // Размер структуры DIOBJECTDATAFORMAT
    DWORD dwFlags;    // Флаг, определяющий работает ли устройство 
                      // в абсолютном режиме (DIDF_ABSAXIS)
                      // или в относительном режиме (DIDF_RELAXIS)
    DWORD dwDataSize; // Размер получаемого от устройства
                      // пакета данных (в двойных словах)
    DWORD dwNumObjs;  // Количество объектов в массиве rgodf
    LPDIOBJECTDATAFORMAT rgodf; // Адрес массива структур
                                // DIOBJECTDATAFORMAT
} DIDATAFORMAT, *LPDIDATAFORMAT;

В большинстве случаев вам не потребуется инициализировать эту структуру, поскольку DirectInput предоставляет вам доступ к ряду ее предопределенных экземпляров.

Таблица 3.5. Адаптированные устройства структуры данных DirectInput


УстройствоПример структуры данных

Клавиатураc_dfDIKeyboard pDIDevice->SetDataFormat(&c_dfDIKeyboard);
Мышьc_dfDIMouse pDIDevice->SetDataFormat(&c_dfDIMouse);
Джойстикc_dfJoystick pDIDevice->SetDataFormat(&c_dfDIJoystick);

Я не буду подробно рассказывать о том, как разработать собственный формат данных. Если вы хотите разработать собственную структуру формата данных устройства, обратитесь к документации DirectX SDK. Эти структуры подходят для данной книги.

Чтение данных

Наконец-то! Функция IDirectInputDevice8:GetdeviceState, которая используется для чтения данных устройства, позволила вам достичь цели. Эта функция требует передачи буфера данных для хранения информации об устройстве для последующего использования. Эти данные варьируются от устройства к устройству, как вы вскоре увидите.

Вот пример функции:

HRESULT IDirectInputDevice8::GetDeviceState(
    DWORD  cbData,   // Размер буфера для хранения данных устройства
    LPVOID lpvData); // Указатель на буфер для хранения данных устройства

Следующий фрагмент кода используется для считывания данных в зависимости от устройства. Он также учитывает, что вы можете потерять устройство и вам потребуется повторное считывание. Необходимо передать указатель на буфер, достаточно большой, чтобы вместить как данные устройства, так и объем, который вы считываете.

BOOL ReadDevice(IDirectInputDevice8 *pDIDevice,
                void *DataBuffer, long BufferSize)
{
    HRESULT hr;

    while(1) {
        // Опрос устройства
        g_pDIDevice->Poll();

        // Чтение состояния
        if(SUCCEEDED(hr = g_pDIDevice->GetDeviceState(BufferSize,
                                               (LPVOID)DataBuffer)))
            break;

        // Возвращаем нераспознанную ошибку
        if(hr != DIERR_INPUTLOST && hr != DIERR_NOTACQUIRED)
            return FALSE;

        // Вновь захватываем устойство и пытаемся
        // получить данные еще раз
        if(FAILED(g_pDIDevice->Acquire()))
            return FALSE;
    }
    // Сообщаем об успехе
    return TRUE;
}

Выводы

  • Если вам необходимо использовать GUID в качестве первичного ключа из-за любого из критериев, упомянутых в начале этой статьи, последовательный GUID, созданный для каждой записи на клиенте, будет лучшим вариантом с точки зрения производительности.
  • Если создание GUID на клиенте по какой-то причине неприемлемо, вы можете использовать NEWSEQUENTIALID() для генерации идентификатора на стороне базы данных. Entity Framework делает это по умолчанию для ключей GUID, созданных на стороне базы данных. Но учтите, что производительность вставки будет значительно ниже, чем при генерации идентификаторов на стороне клиента. Для проектов, где количество вставок таблиц невелико, эта разница не будет критичной. Этого накладного расхода, вероятно, можно избежать в сценариях, где вам не нужно немедленно получать ID вставленной записи, но такое решение не будет универсальным.
  • Если ваш проект уже использует непоследовательные GUID, вам следует рассмотреть возможность исправления этого, если количество вставок таблиц велико, а размер базы данных намного больше доступного объема оперативной памяти.
  • Разница в производительности на других СУБД может быть очень разной, поэтому полученные результаты можно рассматривать только в сравнении с Microsoft SQL Server. Хотя основные критерии, упомянутые в начале статьи, действительны независимо от конкретной СУБД.

Оставьте комментарий

Adblock
detector