Hi Richard,
I took a look at the code you sent me.
In the method MainWindow.OnLoaded
at line 24 you do ConnectRealm().Result
where ConnectRealm is an async method. By using Task.Result to run an async method synchronously, youāre blocking the UI thread. However, due to the way the runtime invokes continuations after an await, the execution context in ConnectRealm will try to return to the main thread. This causes a deadlock where the main thread waits for ConnectRealm to complete and ConnectRealm waits for the main thread to be yielded to continue execution after the first await.
You have 2 options:
1- (Recommended) Call the async method without awaiting it. And in order to be notified when itās done you can use any messaging system that you prefer or you could manually set a boolean telling you when itās done and at specific events check it and take the needed action. I mixed the 2 options below, I hope itās clear:
class MainWindow : Window
{
// ... you vars and other methods
bool IsBusy = false;
public void OnLoaded(object sender, RoutedEventArgs e)
{
MainFrame.Content = " Opening Realm Database";
// pseudo code
yourMessagingSystem.notificationOfInterest += SetContent;
_ = ConnectRealm();
}
private async Task<bool> ConnectRealm()
{
try
{
IsBusy = true;
var user = App.taskApp.CurrentUser;
if (user == null)
{
user = await RealmConnector.GetOrLoginAnonUser(App.taskApp);
}
var dlg = new MessageYesNoWindow("LoginAsync", "Success");
//pseudo call to messaging system
yourMessagingSystem.Notify(...);
}
catch (Exception ex)
{
App.ProcessException("MainWindow.ConnectRealm", ex.InnerException.Message);
}
finally
{
IsBusy = false;
}
}
private void SetContent()
{
MainFrame.Content = "";
}
// more of your code
private void Close_Click(object sender, RoutedEventArgs e)
{
// more pseudo code
yourMessagingSystem.notificationOfInterest -= SetContent
// ...
}
}
2- (Not recommended) If you really canāt do this asynchronously, then you can use a trick where you spin up a background task to do the work and .Result that one. Itās generally discouraged because youāll be blocking the main thread for a non-deterministic amount of time which can result in poor user experience. You should also be careful not to open Realm instances in the background method because those wonāt be usable on the main thread.
The code would look something like this:
class MainWindow : Window
{
// ... you vars and other methods
public void OnLoaded(object sender, RoutedEventArgs e)
{
MainFrame.Content = " Opening Realm Database";
var connected = Task.Run(async () => await ConnectRealm()).Result;
if (connected)
{
MainFrame.Content = "";
}
}
// more of your code
}
Hope this helps,
Andrea