Skip to content

Commit

Permalink
Merge pull request #46 from AArnott/fix43
Browse files Browse the repository at this point in the history
Sleep the WinForms thread without spinning
  • Loading branch information
AArnott authored May 16, 2020
2 parents 68790c2 + 5a0b218 commit 3f3c5c5
Showing 1 changed file with 20 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
namespace Xunit.Sdk
{
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
Expand All @@ -12,6 +14,12 @@ internal class WinFormsSynchronizationContextAdapter : SyncContextAdapter
{
internal static readonly SyncContextAdapter Default = new WinFormsSynchronizationContextAdapter();

#pragma warning disable SA1310 // Field names should not contain underscore
private const uint MWMO_INPUTAVAILABLE = 0x0004;
private const uint QS_ALLINPUT = 0x04FF;
private const uint WAIT_FAILED = 0xFFFFFFFF;
#pragma warning restore SA1310 // Field names should not contain underscore

private WinFormsSynchronizationContextAdapter()
{
}
Expand All @@ -30,10 +38,21 @@ internal override void PumpTill(SynchronizationContext synchronizationContext, T
while (!task.IsCompleted)
{
Application.DoEvents();
Thread.Sleep(0); // give up thread to OS so we don't spin CPU too hard
if (MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 250, QS_ALLINPUT, MWMO_INPUTAVAILABLE) == WAIT_FAILED)
{
throw new Win32Exception();
}
}
}

internal override void InitializeThread() => Application.OleRequired();

[DllImport("user32", SetLastError = true)]
private static extern uint MsgWaitForMultipleObjectsEx(
uint nCount,
IntPtr pHandles,
uint dwMilliseconds,
uint dwWakeMask,
uint dwFlags);
}
}

0 comments on commit 3f3c5c5

Please sign in to comment.