Skip to content

Instantly share code, notes, and snippets.

@noseratio
Created September 27, 2021 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noseratio/0d93133b826339c7eaf49c9feec142e3 to your computer and use it in GitHub Desktop.
Save noseratio/0d93133b826339c7eaf49c9feec142e3 to your computer and use it in GitHub Desktop.
Monitor.Enter pumps some messages including WM_PAINT
// https://github.com/mono/SkiaSharp/issues/1383
// based on https://gist.github.com/retran/b57e4db1a173048c2cee49ac6d523fc2
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WutExample
{
static class Program
{
class MyVeryCustomException : Exception { }
private static readonly object sync = new object();
static void Throw()
{
throw new MyVeryCustomException();
}
[STAThread]
static void Main()
{
var mainThreadId = Thread.CurrentThread.ManagedThreadId;
bool throwOnPaint = false;
var form = new Form();
form.Paint += (sender, args) =>
{
Debug.Assert(Thread.CurrentThread.ManagedThreadId == mainThreadId);
if (throwOnPaint)
{
Throw();
}
};
var button = new Button { Text = "Click Me" };
button.Click += (sender, args) =>
{
var start = System.Environment.TickCount;
Task.Run(() =>
{
Debug.Assert(Thread.CurrentThread.ManagedThreadId != mainThreadId);
lock (sync)
{
// Will send WM_PAINT if called from a non-main thread.
Thread.Sleep(250);
form.Invalidate();
Thread.Sleep(2000);
}
});
throwOnPaint = true;
try
{
Thread.Sleep(500);
// acquiring the lock shouldn't be pumping,
// but it does!
lock (sync)
{
Debug.Assert(System.Environment.TickCount - start >= 2250);
}
}
finally
{
throwOnPaint = false;
}
};
form.Controls.Add(button);
Application.Run(form);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment