Код: Выделить всё
// Arrange
var timeout = TimeSpan.FromSeconds(10);
var locker = new object();
var suspendEvent = new ManualResetEventSlim(false);
ulong threadId = 0;
var thread = new Thread(() =>
{
lock (locker)
{
threadId = InteropAPI.TRGetCurrentThreadId();
}
Log($"Thread started: {threadId}");
suspendEvent.Wait();
Log($"Thread finished: {threadId}");
});
thread.Start();
for (var i = 0; i < 100; i++)
{
lock (locker)
{
if (threadId != 0)
{
break;
}
}
Thread.Sleep(10);
}
Assert.That(threadId, Is.Not.EqualTo(0));
// Act
Log("Suspending thread...");
InteropAPI.TRSuspendThread(threadId);
Log("Thread suspended");
suspendEvent.Set();
Log("Event set");
// Assert part omitted
Эта версия теста работает просто отлично, казнили тысячи раз. Вот немного более чистая версия, которая пытается избавиться от ThreadId Have Hack:
Код: Выделить всё
// Arrange
var timeout = TimeSpan.FromSeconds(10);
var locker = new object();
var suspendEvent = new ManualResetEventSlim(false);
var threadSetEvent = new ManualResetEventSlim(false);
ulong threadId = 0;
var thread = new Thread(() =>
{
lock (locker)
{
threadId = InteropAPI.TRGetCurrentThreadId();
}
threadSetEvent.Set();
Log($"Thread started: {threadId}");
suspendEvent.Wait();
Log($"Thread finished: {threadId}");
});
thread.Start();
threadSetEvent.Wait(timeout);
Assert.That(threadId, Is.Not.EqualTo(0));
// Act
Log("Suspending thread...");
InteropAPI.TRSuspendThread(threadId);
Log("Thread suspended");
suspendEvent.Set();
Log("Event set");
< /code>
Проблема с этой версией, она застряла. В частности, в вызове приостановтию .shipentevent.set () Код: Выделить всё
Thread started: 37348
Suspending thread...
Thread suspended
< /code>
Поток приостанавливается, как и ожидалось, как подтверждено через процесс Explorer. Принудительно возобновление потока, используя процесс Explorer, делает тестовую отделку и распечатайте остальные журналы: < /p>
Event set
Thread finished: 37348
Стек нативного вызовов для тестового потока, во время тупика, кажется: < /p>
Код: Выделить всё
ntdll.dll!NtWaitForAlertByThreadId+0x14
ntdll.dll!TpWorkOnBehalfClearTicket+0x2c3
ntdll.dll!RtlEnterCriticalSection+0x254
ntdll.dll!RtlEnterCriticalSection+0x42
< /code>
стек подвесного потока: < /p>
ntdll.dll!ZwCreateEvent+0x14
KERNELBASE.dll!CreateEventW+0x95
< /code>
[*] Почему выполнение останавливается на suppustevent.set () < /code>? Требует ли вызов set () [*] Этот тест был выполнен в Entine Engine, в которой используется пользовательская версия Mono
Подробнее здесь: https://stackoverflow.com/questions/793 ... her-thread
Мобильная версия