Эта функция может повысить exception_possible_deadlock , также известная как status_possible_deadlock , если операция ожидания в критическом разделе. Интервал тайм -аута указывается по следующему значению реестра: hkey_local_machine \ System \ currentControlset \ Control \ Session Manager \ CritericsectionTimeout . Не обращайтесь с возможным исключением тупика; Вместо этого отлаживайте приложение. С этой целью я создал небольшой скрипт C# с использованием Vanara (.NET Fursers Over Winapi функций): < /p>
#r "nuget: Vanara.PInvoke.Kernel32, 4.1.6"
#r "nuget: System.CommandLine, 2.0.0-beta5.25306.1"
using System.CommandLine;
using System.Diagnostics;
using System.Threading;
using static Vanara.PInvoke.Kernel32;
var sleepMillisecondsOption = new Option("--sleep-milliseconds", "-s") { DefaultValueFactory = (_) => 5000 };
var rootCommand = new RootCommand("Critical section contention") { sleepMillisecondsOption };
rootCommand.SetAction(parseResult => Runner(parseResult.GetValue(sleepMillisecondsOption)));
return new CommandLineConfiguration(rootCommand).Invoke(Args.ToArray());
void Runner(int sleepMilliseconds)
{
var startTime = Stopwatch.GetTimestamp();
InitializeCriticalSection(out var criticalSection);
WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: Started");
var thread1 = new Thread(Worker);
var thread2 = new Thread(Worker);
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: Finished");
void Worker()
{
var threadId = Thread.CurrentThread.ManagedThreadId;
WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: Before EnterCriticalSection");
EnterCriticalSection(ref criticalSection);
WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: After EnterCriticalSection");
Thread.Sleep(sleepMilliseconds);
WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: Before LeaveCriticalSection");
LeaveCriticalSection(ref criticalSection);
WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: After LeaveCriticalSection");
}
}
< /code>
и собрал его в автономный исполняемый файл на .net 8: < /p>
dotnet script publish -c Release ContendCriticalSection.csx
< /code>
Когда я запускаю его на своей машине (Windows 11, 26100.4349), он создает ожидаемый выход: < /p>
00:00:00.0001706: Started
00:00:00.0020008: 4: Before EnterCriticalSection
00:00:00.0021132: 5: Before EnterCriticalSection
00:00:00.0023623: 4: After EnterCriticalSection
00:00:05.0078115: 4: Before LeaveCriticalSection
00:00:05.0082580: 5: After EnterCriticalSection
00:00:05.0084024: 4: After LeaveCriticalSection
00:00:10.0122947: 5: Before LeaveCriticalSection
00:00:10.0126381: 5: After LeaveCriticalSection
00:00:10.0130023: Finished
< /code>
Затем я создал экземпляр Windows на EC2 (DataCenter DataCenter Windows Server 2025, 26100.4061), изменил значение реестра на 2 и перезагрузил экземпляр: < /p>
PS C:\Users\Administrator> reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v CriticalSectionTimeout
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
CriticalSectionTimeout REG_DWORD 0x2
< /code>
Я ожидал, что второй поток поднимет исключение через две секунды, но запуск исполняемого файла в экземпляре EC2 дает один и тот же вывод: оба потока по очереди спят в течение 5 секунд, а затем возвращаются нормально. То же самое происходит, когда я запускаю исполняемый файл с более крупными настройками сна: критический раздел не время ожидания. Значение реестра
hklm \ System \ currentControlset \ Control \ SessionManager \ CriticalSectionTimeout < /p>
Единица для этого значения находится в секундах. Вы должны установить значение
Подробнее здесь: [url]https://stackoverflow.com/questions/79694526/why-is-entercriticalsection-not-timing-out[/url]
Эта функция может повысить exception_possible_deadlock , также известная как status_possible_deadlock , если операция ожидания в критическом разделе. Интервал тайм -аута указывается по следующему значению реестра: hkey_local_machine \ System \ currentControlset \ Control \ Session Manager \ CritericsectionTimeout . Не обращайтесь с возможным исключением тупика; Вместо этого отлаживайте приложение. С этой целью я создал небольшой скрипт C# с использованием Vanara (.NET Fursers Over Winapi функций): < /p> [code]#r "nuget: Vanara.PInvoke.Kernel32, 4.1.6" #r "nuget: System.CommandLine, 2.0.0-beta5.25306.1"
using System.CommandLine; using System.Diagnostics; using System.Threading; using static Vanara.PInvoke.Kernel32;
var sleepMillisecondsOption = new Option("--sleep-milliseconds", "-s") { DefaultValueFactory = (_) => 5000 }; var rootCommand = new RootCommand("Critical section contention") { sleepMillisecondsOption }; rootCommand.SetAction(parseResult => Runner(parseResult.GetValue(sleepMillisecondsOption)));
return new CommandLineConfiguration(rootCommand).Invoke(Args.ToArray());
void Runner(int sleepMilliseconds) { var startTime = Stopwatch.GetTimestamp(); InitializeCriticalSection(out var criticalSection); WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: Started"); var thread1 = new Thread(Worker); var thread2 = new Thread(Worker); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: Finished");
void Worker() { var threadId = Thread.CurrentThread.ManagedThreadId; WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: Before EnterCriticalSection"); EnterCriticalSection(ref criticalSection); WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: After EnterCriticalSection"); Thread.Sleep(sleepMilliseconds); WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: Before LeaveCriticalSection"); LeaveCriticalSection(ref criticalSection); WriteLine($"{Stopwatch.GetElapsedTime(startTime)}: {threadId}: After LeaveCriticalSection"); } } < /code> и собрал его в автономный исполняемый файл на .net 8: < /p> dotnet script publish -c Release ContendCriticalSection.csx < /code> Когда я запускаю его на своей машине (Windows 11, 26100.4349), он создает ожидаемый выход: < /p> 00:00:00.0001706: Started 00:00:00.0020008: 4: Before EnterCriticalSection 00:00:00.0021132: 5: Before EnterCriticalSection 00:00:00.0023623: 4: After EnterCriticalSection 00:00:05.0078115: 4: Before LeaveCriticalSection 00:00:05.0082580: 5: After EnterCriticalSection 00:00:05.0084024: 4: After LeaveCriticalSection 00:00:10.0122947: 5: Before LeaveCriticalSection 00:00:10.0126381: 5: After LeaveCriticalSection 00:00:10.0130023: Finished < /code> Затем я создал экземпляр Windows на EC2 (DataCenter DataCenter Windows Server 2025, 26100.4061), изменил значение реестра на 2 и перезагрузил экземпляр: < /p> PS C:\Users\Administrator> reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v CriticalSectionTimeout
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager CriticalSectionTimeout REG_DWORD 0x2 < /code> Я ожидал, что второй поток поднимет исключение через две секунды, но запуск исполняемого файла в экземпляре EC2 дает один и тот же вывод: оба потока по очереди спят в течение 5 секунд, а затем возвращаются нормально. То же самое происходит, когда я запускаю исполняемый файл с более крупными настройками сна: критический раздел не время ожидания. Значение реестра hklm \ System \ currentControlset \ Control \ SessionManager \ CriticalSectionTimeout < /p> Единица для этого значения находится в секундах. Вы должны установить значение