Vanara/UnitTests/PInvoke/Kernel32/ThreadPoolLegacyApiSetTests.cs

112 lines
3.6 KiB
C#

using NUnit.Framework;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke.Tests
{
[TestFixture]
public class ThreadPoolLegacyApiSetTests
{
[Test]
public void QueueUserWorkItemTest()
{
var cnt = 0;
InitializeCriticalSection(out var g_cs);
try
{
Assert.That(QueueUserWorkItem(ThreadProc, (IntPtr)1, WT.WT_EXECUTEDEFAULT), ResultIs.Successful);
Assert.That(QueueUserWorkItem(ThreadProc, (IntPtr)2, WT.WT_EXECUTEINIOTHREAD), ResultIs.Successful);
Assert.That(QueueUserWorkItem(ThreadProc, (IntPtr)3, WT.WT_EXECUTEINLONGTHREAD), ResultIs.Successful);
Assert.That(QueueUserWorkItem(ThreadProc, (IntPtr)1, WT.WT_EXECUTEINTIMERTHREAD), ResultIs.Successful);
Assert.That(QueueUserWorkItem(ThreadProc, (IntPtr)2, WT.WT_EXECUTEINUITHREAD), ResultIs.Successful);
Assert.That(QueueUserWorkItem(ThreadProc, (IntPtr)3, WT.WT_EXECUTEINWAITTHREAD), ResultIs.Successful);
}
finally
{
while (cnt < 6)
Sleep(500);
DeleteCriticalSection(ref g_cs);
}
uint ThreadProc(IntPtr c)
{
for (var i = 0; i <= 5; i++)
{
//EnterCriticalSection(ref g_cs);
Debug.WriteLine($"Thread {0} (id: {1}) is {2}", c.ToInt32(), GetCurrentThreadId(), i);
//LeaveCriticalSection(ref g_cs);
InterlockedIncrement(ref cnt);
}
return 0;
}
}
[Test]
public void RegisterWaitForSingleObjectTest()
{
SafeEventHandle hCmplEvt;
var start = DateTime.Now;
using (var hEvent = CreateEvent(null, true, false, null))
using (hCmplEvt = CreateEvent(null, true, false, null))
{
Debug.WriteLine("Register wait proc...");
Assert.That(RegisterWaitForSingleObject(out var hWait, hEvent, WaitProc, default, 3000, WT_SET_MAX_THREADPOOL_THREADS(WT.WT_EXECUTEONLYONCE, 503)), ResultIs.Successful);
using (hWait)
{
hWait.WaitForAllFunctions = true;
Sleep(1000);
Assert.That(hEvent.Set(), ResultIs.Successful);
}
Debug.WriteLine($"{(DateTime.Now - start).TotalSeconds} Exiting wait proc...");
}
void WaitProc(IntPtr lpParameter, bool TimerOrWaitFired)
{
Debug.WriteLine($"{(DateTime.Now - start).TotalSeconds} In wait proc (TimerOrWaitFired={TimerOrWaitFired})...");
}
}
[Test]
public void TimerQueueTest()
{
// Use an event object to track the TimerRoutine execution
SafeEventHandle gDoneEvent;
using (gDoneEvent = CreateEvent(null, true, false, null))
{
Assert.That(gDoneEvent, ResultIs.ValidHandle);
// Create the timer queue.
using (var hTimerQueue = CreateTimerQueue())
{
Assert.That(hTimerQueue, ResultIs.ValidHandle);
// Establish that all callback functions are complete before disposing.
hTimerQueue.CompletionEvent = SafeEventHandle.InvalidHandle;
// Set a timer to call the timer routine in 2 then 1 second.
Assert.That(CreateTimerQueueTimer(out var hTimer, hTimerQueue, TimerRoutine, default, 2000), ResultIs.Successful);
Assert.That(ChangeTimerQueueTimer(hTimerQueue, hTimer, 1000, 0), ResultIs.Successful);
// TODO: Do other useful work here
// Wait for the timer-queue thread to complete using an event object. The thread will signal the event at that time.
Assert.That(WaitForSingleObject(gDoneEvent, INFINITE), ResultIs.Value(WAIT_STATUS.WAIT_OBJECT_0));
// Forceably delete the timer.
Assert.That(DeleteTimerQueueTimer(hTimerQueue, hTimer, SafeEventHandle.Null), ResultIs.Successful);
}
}
void TimerRoutine(IntPtr lpParam, bool TimerOrWaitFired)
{
SetEvent(gDoneEvent);
}
}
}
}