solodeving
solodeving

Reputation: 51

ReactiveUI async freezes

I am making some Avalonia MVVM app.

When the 'Log In' button is pressed, it looks in the database to see if the account matches, and this operation takes about 1 second. So in order to not freeze the UI for one second, I used await/async :

Login command:

private async Task loginCommand()
{
      //see if it exists in db
      using (var dbcontext = new DatabaseContext())
      {
          var user = await dbcontext.Credentials.FirstOrDefaultAsync(u => u.Email == this.Email);

          if (user == null)
          {
              //email not found
              await ShowErrorEmail();
              return;
          }

          if (user.Password != this.Password)
          {
              // incorrect password    
              await ShowErrorPassword();
              return;
          }

          //good to go
      }
}

Command definition:

var isInputValid = this.WhenAnyValue(x => x.Email, x => x.Password,
     (email, password) => (!string.IsNullOrWhiteSpace(password)
     && !string.IsNullOrWhiteSpace(email)));
     
LoginCommand = ReactiveCommand.CreateFromTask(loginCommand , isInputValid);

I debugged and found out that FirstOrDefaultAsync() takes about 1 second, but I awaited it so I have no idea why the UI freezes. Thanks!

Upvotes: 0

Views: 119

Answers (2)

QmlnR2F5
QmlnR2F5

Reputation: 1279

Some database providers, such as SQLite, do not actually support async operations, so all the ...Async() calls are actually synchronous. If you're using such database provider, as a workaround you could wrap each call in a Task.Run().

Upvotes: 0

Jacob Proffitt
Jacob Proffitt

Reputation: 12778

My guess is that it isn't the FirstOrDefaultAsync that's blocking but the call to dbcontext.Credentials. If you want to test that, wrap that in its own Task.Run. That way it's all on a separate thread, not just the FirstOrDefaultAsync bit.

Upvotes: -1

Related Questions