-2

I wonder that is it a good practice to bind an event to an async Task method by using x:bind?

Basically, I'm using MVVM, which my ViewModel contains some async Task method, and I want to x:bind the async Task method to an event in my view (which is actually works fine), however, I hear that we shouldn't make an event into an async Task.

Here's some code example:
Event x:bind to async Task method

SomeViewModel.cs

public class SomeViewModel
{
    public async Task DoneAsync()
    {
        //...some code
    }
}

SomeView.xaml

<button context="click" click="{x:bind DoneAsync}"/>


Curently what I did is to use async Task in code behind instead, for safety.

SomeView.xaml

<button context="click" click="Done_clicked"/>

SomeView.cs

public async void Done_clicked(...)
{
    await vm.DoneAsync();
}
Chung Wei Leong
  • 184
  • 1
  • 7
  • As far as I know, you have to bind to `void` methods, regardless if `async` or not – Camilo Terevinto Sep 23 '17 at 02:28
  • Why are you using x:bind instead of commands? – AzzamAziz Sep 23 '17 at 02:48
  • 1
    That's async void, and it's OK. You don't have to use async Task for UI event handlers. – Justin XL Sep 23 '17 at 03:11
  • 4
    @JustinXL: _"You don't have to use async Task for UI event handlers"_ -- more specifically, you _can't_ use `async Task` for UI event handlers. – Peter Duniho Sep 23 '17 at 04:22
  • 1
    Some reference: [Async/Await - Best Practices](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx), [async/await - when to return a Task vs void?](https://stackoverflow.com/q/12144077/2681948). – Romasz Sep 23 '17 at 04:34

1 Answers1

4

If you're following the MVVM pattern it is better to avoid events and use Commands instead.

I don't have the code compiled so it may not be %100 accurate but this is the idea.

<Button Context="Click" Command="ButtonClickedCommand" />

In your ViewModel you'd need a delegate command defined at the global level.

DelegateCommand ButtonClickedCommand

In your MVVM constructor you need to initialize it to your method.

ButtonClickedCommand = new DelegateCommand(ButtonClicked);

Now your method. This should be async.

public async void ButtonClicked()
{
    // Your code here.
}

Why should your code be async?

Your UI method should be async so that it avoids freezing the UI and interrupt the user.

Why is my async an async void and not an async Task?

An async Task will force the code to wait on the code. async void will call the task and not know when it is done. Since this is UI related, we don't care to hear back from it.

AzzamAziz
  • 2,144
  • 1
  • 24
  • 34
  • This does not answer the question. Click method handlers are perfectly fine to use, even when implementing MVVM. Yes, the ICommand approach generally fits the pattern, but it doesn't mean event handlers should never be used, especially with the advent of `{x:Bind}` – jeff17237 Feb 03 '22 at 00:20