Best Practices – When to use async void | The Xamarin Show


>>Tune in in this week’s Xamarin
Show where my good friend, Dean, comes on to talk
about async void. Yes, async void, and
why not to use it, and how to fix your code. So tune in. [MUSIC]. Welcome back everyone
to The Xamarin Show. We’re back again with
my good friend, Dean, to talk about best
practices for async await. Now Dean, you’ve done introductory, advanced, but I think we
miss something important.>>Yeah.>>The dreaded async.>>Async void.>>That is correct. Yes.>>Yeah. This one’s a huge catcher.>>So what is async void
and why is it an issue?>>Yeah. So with AsyncTasks, usually you want to return a task and then on the task,
you can await it. The reason that the async keyword is there isn’t because
you’re returning a task, but actually within that
method, there’s an await. So you can’t call await if
you don’t have an async. So sometimes when a method
doesn’t return anything, you’d make it into a
void method, right?>>Yeah. Like, oh, I don’t need
anything back so why bother?>>Why bother returning
something? This is extra stuff. So what happens when there’s
an await inside of it, then you have to put async on it. Then what happens is whenever
an exception is thrown, the exception can disappear.>>Oh, got you. So it’s
very, very tricky. I’ve always heard and you’ll
always see it on Twitter, everywhere, async void, evil.>>Exactly.>>All right. We’ll see what you got. Let’s take a look at the code.>>All right. So let’s take a look. So this is a command. When you click “Button”,
it’ll just run this. Here, we have an async void
method within a try-catch block.>>So I see it right below there, right on Line 55. Now this looks okay, right? I’m going to be calling, I assume, an await method inside of that async void method.
Right there, I see a boom.>>Yeah, right here.>>Line 64. Yeah. So this looks good. So async, it was void only
because I needed to await.>>Exactly.>>So really, like you said, async await doesn’t actually
mean you have to have a task because the async
is pairing with the await.>>The await, internally.>>So you’re thinking here,
“Wow.” It’s probably squiggly.>>Yeah.>>You want to get
rid of the squiggles. That’s how you do it, right?>>Exactly. Yeah. Just add this
async and then you can run it.>>Yeah. Okay.>>So the problem with
async void is you can’t actually await the method
even though it’s async. So here, we see our void method. But I can’t await on
it because it’s void.>>Okay, got you. So it’ll just go?>>Exactly, yeah. So you can only await on tasks. So, yeah. It’s going to complain. So let’s take a look at what
happens when you execute this.>>What does that do,
that async void method? So we know what to expect.>>Yeah. So this just runs a task that runs for two seconds
and then returns a string.>>Okay, got you.>>The test string. But in this
case we’re ignoring that return. So we’re not returning anything
and the signature is just void.>>Okay, got it.>>All right. So let’s take
a look if we just run that. So we’ll see that the command ended and then the
application blew up.>>Oh, no.>>What’s the deal,
right? I had a try-catch.>>Yeah. It looks good.>>Yeah?>>Yeah.>>What’s the deal?>>What the heck, Dean.
What’s going on man?>>Come on Visual Studio.>>Yeah.>>Let’s go in that.
So what happens is if we take a look and
we look carefully, we’ll see command ending actually happened before the async
void method completed.>>Oh, okay. Got it.>>So because we couldn’t
await it because it was void, then we just had to
continue execution. Then once it threw the exception, it just threw up to the ether.>>Somewhere.>>Yeah.>>In this instance, it was->>It was Visual Studio.>>It was Visual Studio and the
app, the whole app crashed.>>Yeah, the whole app crashed.>>Got you.>>So that’s that’s that. That’s async void and why
you should not use it.>>Yeah. How do I fix it?>>So to fix it, you
could return, let’s see. You could just return a task or you could have a
try-catch within it.>>Okay.>>So if you just add a try-catch there then because
you’re awaiting here, oh, actually this is try-catch. Oh, here because we’re
throwing internally.>>I see.>>Okay. So we already
have the try-catch but we’re throwing it because if
this is an internal library, maybe you want to bubble
up that exception. So if you don’t throw it and you
handle it internally, it’ll work. But you never know with internal libraries that
might have async void.>>Got it. So would you say the
best practice here would actually not to be to handle it here
but probably add task.>>Exactly. So instead
of an async void, you could make it into a task
with the task completion source, Asyncify it, and then you
can await it properly.>>All right. So it’s
throwing an exception, so how do we fix it?>>Yeah, that is pretty simple. So instead of returning void, we just returning task.>>Okay.>>Because it’s an async method, we don’t actually have to return anything and it will
just accept that.>>Okay, cool.>>So let’s check it out
here. So it’s a task.>>So let’s add the name space. Then here in the calling method, it’ll give us squigglies
because we’re not awaiting. So let’s await that properly so
we can handle the exception. You just need to add
async to this Lambda and the command and
then await right here. Then this should run as we expect.>>Now in that method, it was throwing an exception before? So is it still going to
throw that exception?>>Yes. It’s still going
to throw the exception. We didn’t change the method. We just changed it to a task.>>Wow, let’s check it out.>>All right. Here we need, oh, no.>>Yeah. Don’t need
to return anything.>>Yeah. All right.>>Let’s say you can’t
change your signature to it. Let’s say it has to be void
because it’s an event.>>Yeah.>>Right? How would you handle that?>>So in that case, I would maybe do a test to
out run with a continuous.>>Okay.>>Then handle the fault
continuation option.>>Okay.>>Yeah. So that’s one way to do it. I think that might be
the best way actually.>>Yeah.>>Yeah.>>Got it, cool. All right.
Let’s take a look at it now.>>All right. We have->>Async void.>>Async void, try-catch. All right. So we’ll see the test started
and we haven’t completed. Then our exception is caught.>>Boom.>>Async void exception.>>Easy-peasy.>>There you go.>>So get rid of your async
voids, unless you can’t. Then can you do that, or handle all the exceptions in there, right?>>Exactly.>>I’ll do the other thing.
Very cool, easy-peasy. Async void, don’t do it. Task, task are your friend, right?>>Yeah.>>Nice.>>Exactly.>>Now, how often do you
see this on the wild too? Because to me it’s like,
“All right. Cool, Dean. Cool demo.” But like is this a
thing that people are doing?>>This is a very big thing, very big because it’s
very easy to miss this kind of exception within
a task because in.NET, everything can be caught, try-catch. That’s the way we do it. But it’s sneaky when
you have task that complete with an exception
that don’t really throw.>>Got you. Very cool.>>Yeah.>>All right. Anything
else for async void?>>Use it properly now
that you know how to.>>Very cool. Dean,
thank you so much for the [inaudible] quick best practice. You can find all of Dean’s code, all of his best practices for async
await and the entire series of best practices for Xamarin at
aka.MS/Xamarinbestpractices. Dean, thanks so much
for this quick one.>>Thanks so much, James.>>Awesome. Thanks
everyone for tuning in. Don’t forget to subscribe
wherever you’re watching right now for more Xamarin awesome. I’m James Montemagno. This is The Xamarin Show
and thanks for watching. [MUSIC]. Hey, James here. Just
wanted to check in and thank you for
watching this video. Now, do all the things that you
know you want to do such as like, subscribe, and ding
that notification bell, become part of the
notification squad. While you’re here, check out all these awesome videos
that I’ve already recorded. Click on that thing. Click
it. Watch it. Do it.

Leave a Reply

Your email address will not be published. Required fields are marked *