Invoking Code on the Main Thread is not Working in .NET 7.0 Mac

116 views Asked by At

I am trying to make an Avalonia app, and part of that is implementing a native alert dialog. However, I can't seem to invoke and alert dialog on the main thread. Below is a screenshot of my code in Visual Studio Mac, with an offending Exception:

enter image description here

It says I can only call this in the Main thread, but... I INVOKE on the main thread, and even added a check to ensure I was indeed on the main thread. I feel like I am missing something very basic here, but I don't know what it is.

Have also tried:

  • Using NSApplication.SharedApplication.InvokeOnMainThread
  • DispatchQueue.MainQueue.DispatchAsync (from CoreFoundation)
  • Dispatcher.UIThread.Post (from Avalonia)

I've also checked without any of these invocations, and I am on the Main Thread already anyways.

1

There are 1 answers

1
sonic1015 On BEST ANSWER

So, this may not technically be an answer, it's more of a work-a-round...

Even though I am on the main thread, there is an internal check done by .NET to ensure that the current thread is also the main thread, and this is what is failing. The function call is NSApplication.EnsureUIThread(), and the source code on Github looks like this:

public static void EnsureUIThread ()
{
    if (NSApplication.CheckForIllegalCrossThreadCalls && NSApplication.mainThread != Thread.CurrentThread)
        throw new AppKitThreadAccessException ();
}

This gets called in the constructor of NSAlert and for whatever reason, it's failing.

Luckily, there is a way to temporarily disable this check:

var illegalCallCheckState = NSApplication.CheckForIllegalCrossThreadCalls;
NSApplication.CheckForIllegalCrossThreadCalls = false;
    
// do things
    
NSApplication.CheckForIllegalCrossThreadCalls = illegalCallCheckState;

And with this little hack, I am able to display dialogs. Hurray. If anyone knows why the check is failing in the first place and a way to properly run this code on the UI thread, I can mark that as the accepted answer.