-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Platform: windows (I am using this project as basis for supporting native AOT).
Steps to reproduce:
- Create form
- Add Load event handler:
Load += (_, _) => {
ThreadPool.UnsafeQueueUserWorkItem(_ =>
{
Thread.Sleep(1000);
for (var i = 0; i < 100; i++) {
Invoke(() => _label.Text = $"Current: {i}");
Thread.Sleep(300);
}
}, null);
};- Run app
- Do resize
Expected result:
_label.Text is continuously updated
Actual result:
_label.Text stops being updated during and after resize
Reason:
This is because Invoke is handled by posting ASYNC_MESSAGE into message loop and expecting the message to be returned by GetMessage/PeekMessage. The issue is that when form is being resized it enters a resize message loop thus our calls to GetMessage/PeekMessage are "bypassed".
Possible fix.
Handle ASYNC_MESSAGE in WndProc instead of XplatUIWin32.GetMessage (this will also require the foster parent to have non-DefWndProc). This is what I have done locally.
Also consider using ASYNC_MESSAGE as a marker and store pending calls in a queue instead of actually sending call info via GCHandle (this is what dotnet/winforms does).
Also possible issue (not sure though): Control.GetInvokableHandle will call CreateHandle if handle does not exist. I am afraid that could cause the handle to be created on a wrong thread if Invoke is called before the control was created. But I don't know if that's a real issue or not I haven't encountered that (haven't tested it either).