Search code examples
wpfasync-awaitmvvm-lightrelaycommand

Why does async method block MVVM Light Relay Command


I'm new to async and need to consume an API that has it. I've read I should "go async all the way" back the UI command. So far I've propagated async back to my view model.

The code below blocks the Upload button in my UI. Is this because the RelayCommand's implementation calls it using await?

// In the ViewModel:
public MyViewModel()
{
   ...
   UploadRelayCommand = new RelayCommand(mUpload, () => CanUpload);
   ...
}

private async void mUpload()
{
   ...
   await mModel.Upload();
   ...
}

// In the model:
public async Task UploadToDatabase()
{
   ...
   projectToUse = await api.CreateProjectAsync(ProjectName);
   ...
}

// In the API
    public async Task<Project> CreateProjectAsync(Project project){}

Update: Sven's comment led me to find that CreateProjectAsync was running in a simulation mode that synchronously wrote to memory. When I wrapped that end code in Task.Run, it no longer blocked my Upload button. When not running in simulation mode, the API natively makes asynchronous calls to interact with a web server, so those also don't block.

Thanks.


Solution

  • The await itself will not block your UI. It is more likely that your Upload() method does not do any real asynchronous work.

    (As Jim suggested, Task.Run() can be used in such a case. It will use the thread pool to run the operation in the background. Generally speaking, for IO-bound operations like uploads/downloads you should check if your API supports asynchronous calls natively. If such an implementation exists, it may make more efficient use of system resources than using a thread.)