Доступны ли функции LoadLibrary, FreeLibrary и GetModuleHandle Win32 потокобезопасными?
Я работаю над веб-сервисом, который взаимодействует с родной DLL, и я использую LoadLibrary/GetModuleHandle/FreeLIbrary и GetProcAddress для динамической загрузки/выгрузки DLL, потому что он не очень стабилен.
public class NativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr LoadLibrary(string libname);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string libname);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
}
Я заметил, что процесс w3wp.exe вызывает сбои при большой нагрузке, и когда я пытался отлаживать его, отладчик часто останавливается при вызове функции NativeMethods.GetModuleHandle().
Я не мог найти никаких доказательств того, что GetModuleHandle
не является потокобезопасным, поэтому мне интересно, имеет ли кто-нибудь подобный опыт при взаимодействии этой функции kernel32.dll из многопоточных приложений .NET?
Оскар
Ответы
Ответ 1
По словам Игоря Тандетника (Microsoft MVP).
Помимо функций GDI, которые не являются потокобезопасными. Почти все, что принимает HWND
и/или HDC
, должно быть вызвано в том же потоке, где были созданы HWND
или HDC
(SendMessage
, PostMessage
и другие аналогичные исключения). HBITMAP
s, HICON
, и такое может быть передано между потоками, но должно управляться одним потоком за раз.
Большинство других функций - те, которые не имеют отношения к GDI или управлению окнами - действительно являются потокобезопасными.
Это должно включать LoadLibrary
, GetModuleHandle
, FreeLibrary
и GetProcAddress
.
Имейте в виду, что FreeLibrary
не следует вызывать из DllMain.
Я также могу добавить, что я использовал эти функции в многопоточной среде довольно долгое время без проблем.