Why is async void bad and how do I await a Task in an object constructor in C#?

Поділитися
Вставка

КОМЕНТАРІ • 228

  • @meJevin
    @meJevin 4 роки тому +19

    Your channel is extremely underrated. Your production quality is insane and the information I’m getting out of these videos is really useful. Thanks dude!

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Thank you so much for the kind words. It motivates me to create more content.

    • @MichaelJoe212
      @MichaelJoe212 Рік тому +1

      short and to the point & solves problems with quick useful examples instead of long lectures -- channel is very underrated!

  • @diegoronkkomaki6858
    @diegoronkkomaki6858 4 роки тому +17

    Great to-the-point video. I appreciate short videos like this, which teach you something in under 10 minutes as rarely does one have time for ~1h tutorials.

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Thank you so much for the kind words. My goal is to always keep my tutorials to under 15 minutes max.

  • @alexanderkvenvolden4067
    @alexanderkvenvolden4067 Рік тому +1

    I like this a lot better than the typical "just don't use async void" advice. I do use a similar method for the "fire and forget" use case that is an async void at the bottom layer, but also has a catch(Exception) and mechanism for handling exceptions.

    • @BrianLagunas
      @BrianLagunas  Рік тому

      Great to hear. I try to be pragmatic when it comes to dev.

  • @VinuP2023
    @VinuP2023 4 роки тому +2

    This is super helpful Brian. Please make more of these short and to the point videos. You know what, this video of yours got so much attention and great feedback from your viewers. Thanks much :)

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Thank you for your kinds words sir. Let's make a deal. If you share my videos with everyone you know, I'll create more videos. Deal? 😁

    • @VinuP2023
      @VinuP2023 4 роки тому +2

      @@BrianLagunas Deal 😃😃
      I will surely share with people I know in software field

  • @dotMorten
    @dotMorten 4 роки тому +3

    Nice one! My simple rule of thumb: If you're forced to do async/void, you MUST have a try/catch block to deal with failures (which your extension in the end is essentially doing). Also not all .NET implementations silently fail but will bring down the entire application process if there's an unobserved task, so your first example of throw could bring down an entire app.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      That great to know. I haven't run into that yet personally, but I can see it definitely happening. Thanks for pointing that out.

    • @SharpGIS
      @SharpGIS 4 роки тому +1

      @@BrianLagunas yeah I believe that's the behavior on .net native 😃.
      You can use the UnobservedTaskException global event to handle it though but again that's a last resort instead of your more elegant solution.

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Did you reply to your comment using a different account 🤣

    • @SharpGIS
      @SharpGIS 4 роки тому +1

      @@BrianLagunas I got split personality disorder when it comes to Google accounts 😃

  • @kopilkaiser8991
    @kopilkaiser8991 Рік тому +1

    I really learnt a lot from this video. Not just the main topic which was discussed but how to give callbacks and using Actions to code formative and constructive code. Thank you bro. I am always following your coding practics as they are well formulated. Your explanation is easy to understand as well.

    • @BrianLagunas
      @BrianLagunas  Рік тому

      Thank you very much. I appreciate you.

  • @longuinni
    @longuinni 4 роки тому +3

    Holy moly.... that was WOW. Very very helpfull. Please make more videos like this one...

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Thank you so much Fernando! I'll try my best 😀

  • @AvnishKumar7
    @AvnishKumar7 4 роки тому +3

    Wow, As a UWP Developer, it helps me a lot. Thanks, Brian

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Thank you for watching. I'm glad this video was helpful.

  • @expertreviews1112
    @expertreviews1112 2 роки тому +1

    fantastic video! like your content on multitasking/async programming is incredible!

  • @thomasbarratt5333
    @thomasbarratt5333 Рік тому +1

    Great solution! This helped me avoid having to bring in numerous additional dependencies into a very large legacy solution. I've expanded onto your extension method for Task
    public async static void Await(this Task task, Action completedCallBack, Action errorCallBack)
    {
    try
    {
    T result = await task;
    completedCallBack?.Invoke(result);
    }
    catch (Exception ex)
    {
    errorCallBack?.Invoke(ex);
    }
    }

  • @niranjannt637
    @niranjannt637 2 роки тому

    Really awesome way to handle async void !!! Thanks.

  • @matiascatanzariti1195
    @matiascatanzariti1195 4 роки тому +2

    Great video found by chance for a problem I'm having. But don't want to miss this opportunity to tell you that your content in general is great. Your courses at pluralsight are great. But most important: I am really in love with Prism.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Thank you so much. I greatly appreciate you and your kind words.

  • @sneeznoodle
    @sneeznoodle 3 роки тому +1

    Really helpful, even though my problem wasn't the exact thing described in this video, it still _really_ helped me fix it. Great video!

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      So happy to hear that. Thanks for watching

  • @beautifulheartsoothingreci28
    @beautifulheartsoothingreci28 4 роки тому

    Let's say you want to navigate to a page and on navigation to it you want to fetch data from the database and display in a list on that page. However I do not want the UI to be blocked while the data is being retrieved and I just wanna display an ActivityIndicator for that duration. Should I call "FetchDataFromDb().Await(...)" in the constructor of that page?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Usually, when navigating in an application, there is some type of built in navigation life-cycle that you can use to load your data.For example, in Prism I know when a view is beging navigated to or away from. I can use methods such as OnNavigatedTo to execute that code. However, if you do not have hooks like that, then yes. You can use this method to fire off an async method to fetch your data, and when that operation is completed you can hide your busy indicator.

  • @231kickback
    @231kickback 3 роки тому +1

    Thanks for the video! I appreciated that the information was straight to the point.

  • @kleberbueno.1978
    @kleberbueno.1978 2 роки тому +1

    Really great amazing tutorials. Keep doing that.

  • @CRBarchager
    @CRBarchager 7 місяців тому

    Great explaination. I try to avoid async void when ever possible. The only place I've seen it used have been in developement with Winforms but nonetheless a good solution to the problem.

  • @Mareinsula
    @Mareinsula 4 роки тому +3

    Reading your code feels like perfection. Thank you! With that now I think I can extend for many properties that require async to be filled.

  • @chrismantonuk
    @chrismantonuk 4 роки тому +3

    Thanks Brian! Nice content and really like your presentation style. Quick question: would there be an issue awaiting the Task inside a void extension method? (Which then also has to be async). Thanks!

    • @BrianLagunas
      @BrianLagunas  4 роки тому +3

      As long as you pass your callbacks down the extension method stack it should be just fine. Thanks for watching.

    • @chrismantonuk
      @chrismantonuk 4 роки тому +2

      Brian Lagunas thanks for the reply. I’ve always wrestled with how to await tasks in a constructor, so this is something I will start implementing straight away. Cheers!

  • @pramod722
    @pramod722 3 роки тому +1

    Thanks Brian for the solution👍

  • @nandkishorsonwale
    @nandkishorsonwale 3 роки тому +1

    Great Solution. Thank you.

  • @NickBullCSharp
    @NickBullCSharp 4 роки тому +2

    Wow this is fantastic. I didn't know about that this was occurring. Thanks Brian 👍

  • @sergiotardo
    @sergiotardo 4 роки тому +1

    That's great!!!! I was looking for some solution to this situation,... a contructor that call a service to get data or anything that need to be done in an async way thanks a lot!!!!! excelent video as always!

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Glad it helped. Thanks for watching

  • @danzk
    @danzk 3 роки тому +1

    Very helpful, thanks for the video!

  • @DevMicha
    @DevMicha 4 роки тому +1

    Great and very useful video.
    Thank you very much!

  • @Zonawanialonnua
    @Zonawanialonnua 4 роки тому +1

    Incredible, it turns out it was easy!
    Thank you, Brian!

  • @Emis333
    @Emis333 3 роки тому +1

    Very nice and useful. Congrats.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      Thanks for watching

    • @Emis333
      @Emis333 3 роки тому

      @@BrianLagunas BTW how would the extension method look like when, say i am expecting a result from an async method Task, and i need it in a non async method or constructor?

    • @BrianLagunas
      @BrianLagunas  3 роки тому +1

      @@Emis333 Like this github.com/PrismLibrary/Prism/blob/master/src/Prism.Core/Extensions/TaskExtensions%7BT%7D.cs

    • @Emis333
      @Emis333 3 роки тому

      @@BrianLagunas Amazing thanks :)

  • @stefan-d.grigorescu
    @stefan-d.grigorescu 2 роки тому +1

    Awesome stuff, thank you for this idea!
    I wonder why isn't this extension already part of the microsoft libraries since these situations with the constructor seem to happen from time to time.
    Or why isn't there some logic to enforce an async constructor behavior?

    • @BrianLagunas
      @BrianLagunas  2 роки тому

      Microsoft isn’t too opinionated about how things should be done. That’s probably a good thing.

  • @GELSAV777
    @GELSAV777 5 місяців тому

    Good video. I don't get one moment. How did background thread from thread pool changed text on UI? Method DoSomething is executed fully on background thread?

  • @ievheniiierokhin1677
    @ievheniiierokhin1677 4 роки тому +1

    Nice tips for Tasks...great job!!!

  • @Kerbargos
    @Kerbargos 4 роки тому +1

    Hey Brain I think you can be a king :) Thank you very much. I think this a life saver for a task implementetion. Very good job.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Thank you very much for the kind words

  • @MrSmsajin
    @MrSmsajin 2 роки тому

    Superb Video! Appriciated! how can we await a Task in an object constructor which is returning the result?

  • @munawarkhurshid1201
    @munawarkhurshid1201 3 роки тому

    Brian can you suggest a work around for Delegate Command. How can I await execute Action in the delegate command. Here is a Delegate Command created in the VM constructor
    this.RefreshTimeCommand = new DelegateCommand(loadTime, canLoadTime).ObservesProperty(() => canRefresh);

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      Yeah, check out this video ua-cam.com/video/O1Tx-k4Vao0/v-deo.html

  • @julianturner6203
    @julianturner6203 4 роки тому +1

    Yes, do more please. Thanks Brian

  • @paulstanley2789
    @paulstanley2789 4 роки тому +1

    Thanks for the awesome tutorial Brian really useful!

  • @kasozivincent107
    @kasozivincent107 4 роки тому +1

    Hello Brian. Thanks for this masterpiece. I remember telling you my views were lagging behind coz I was querying my dB from the constructor, this is going to save my day. In addition, could you one day make a video about The Infragistics Word and Excel engines plus the XamSpreadsheet control? I find the docs not really helpful. At least your videos make everything seem stupid easy. Thanks

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Sure thing. I do plan on doing videos on Infragistics products very soon. This is a popular request from our customers.

    • @kasozivincent107
      @kasozivincent107 4 роки тому +1

      Thank you. Trust me this will save lives. As you always say “one can’t miss what they don’t know” I have infragistics on this machine, I can smell the amount it can fetch me if I built apps using it. But it’s not easy to use. I am waiting for those videos as you waited for your new machine😹😹.

  • @arielspalter7425
    @arielspalter7425 4 роки тому +1

    Fantastic tutorial. Subscribed!

  • @emiliowildberger7151
    @emiliowildberger7151 3 роки тому +1

    Thank you very much Brian, I have learned a lot from you

  • @MrBan001
    @MrBan001 4 роки тому +1

    Why is this Extension not part of the Framework? There must be a reason?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Good question. Maybe they have plans to natively support fire and forget tasks in the ctor in a future release of C# 😁

    • @MrBan001
      @MrBan001 4 роки тому

      @@BrianLagunas IHost for example blocks the thread completele until shutdown after they call Run()

    • @MrBan001
      @MrBan001 4 роки тому

      Mh thats not async ...

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@MrBan001 I'm not sure I understand what you are trying to say, but this extension allows your async code to run on it's worker thread, while the rest of your sync code executes on the UI thread. You can also control which thread the CompletedCallback runs on by using COnfigureAwait in the extension.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@MrBan001 Are you talking about calling BuildWebHost(args).RunAsync() in the Main method in an ASP.NET Core app? If so, that's a completely different animal.

  • @HrishiGhadekar
    @HrishiGhadekar 4 роки тому +3

    That was awesome. I learn MVM with prism from your videos. Can you have or create a tutorial on MVVM on dotnet core?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Sure can, but it won't be any different than an MVVM video for .NET Framework. It's literally the same. Is there something specific you are having troubles with?

  • @thomasberthelsen9581
    @thomasberthelsen9581 3 роки тому +1

    Our application has crashed... This is good! haha, that was nice way to put it :D

  • @InterRubke
    @InterRubke 4 роки тому +1

    Could you do a vid about TaskValue and when is it appropriate to use?

  • @charlinagramonte3471
    @charlinagramonte3471 4 роки тому +1

    Love it. Really nice video Brian!!!!! :)

  • @osman3404
    @osman3404 4 роки тому +3

    OMG! how am I just finding out about this simple technique :)
    By the way Brian, was there ever an explanation from MS as to why constructors are not allowed to have an await? I get. the feeling that it must be a good reason from application design prospective.
    For example I like the ViewModel constructors synchronously setup the default values for all the properties, wire the command handlers then give the View do its bindings. And once the UI is in valid loaded state, await in constructor limitation to enforce a coding practice.

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Using await in a constructor would mean that the constructor would have to return a Task that represents a value that will be constructed in the future, instead of immediately returning the constructed value. This may cause a number of issues, if not a ton of confusion. That's just a guess though.

  • @eltrukof
    @eltrukof 3 роки тому +1

    thanks for the explanation

  • @_samirdahal
    @_samirdahal 4 роки тому +1

    Very good video 👍. Actually I was searching about the same topic. Thank you for sharing. But I have one more question. In real world project, is it a good practice to actually call a task method in a constructor? I mean the constructor is doing a lot of things then. The below code will only execute after awaiting the task? So other fields will initialize late. 🤔. Please can you explain this to me?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +2

      There are usually better places to call async methods when creating an object. However, sometimes you need to do something in a ctor. No, the task is async and will not block the other fields from being initialized. The ctor will run exactly the same as if you didn't call an async method. Try it for yourself and you will see

  • @hanspetervollhorst1
    @hanspetervollhorst1 4 роки тому

    But the extension method itself is still not awaited, or is it? If we had an instruction in the constructor after DoSomething().Await() then it would still be called immediately and not after DoSomething() completed? I don't really understand why the exception inside the Await() Method leads to the application crushing while an exception inside DoSomething() is being ignored

    • @hanspetervollhorst1
      @hanspetervollhorst1 4 роки тому

      DoSomething().RunSynchronously() appears to be a safer approach here, no?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Yes, the extension method awaits the Task. Correct, the invocation f code will continue after the DoSomething().Await() method call. However, you use the completed callback of the extension method to invoke any code you want in response to the completion of the task. Tasks exceptions are thrown within the context of the task. This is why async void is so bad as the exceptions are not handled properly.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@hanspetervollhorst1 You do not want to try and force async code to run synchronously.

  • @krzysztofstepnikowski4150
    @krzysztofstepnikowski4150 4 роки тому +1

    Perfect! This can help me! Awesome! Thanks :)

  • @tomnolane
    @tomnolane 3 роки тому +1

    very very very thanks, it's usefull

  • @n.sharma5810
    @n.sharma5810 Рік тому

    Hi Brian, if possible please create a series on wpf mvvm for beginners

    • @BrianLagunas
      @BrianLagunas  Рік тому

      What does that series look like to you?

  •  2 роки тому +1

    Thanks dude! awesome.

  • @shavais33
    @shavais33 3 роки тому

    I like the Completed, HandleError callback pattern, but if you await from your main thread, it will block, causing your entire app to be unresponsive for 3 seconds. That kind of defeats the purpose of doing something in a background thread. I'd like to see a good way to run async tasks from the main thread without blocking the main thread.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      If the method you are awaiting is async, then it will not block your main thread.

    • @shavais33
      @shavais33 3 роки тому

      @@BrianLagunas But you can't call an async from a non-async.. Oh I see what you're doing, you're calling your Await extension without await-ing it. Ok that's brilliant. You just earned yourself another subscriber.

  • @sergiigolembiovskyi1365
    @sergiigolembiovskyi1365 Рік тому +1

    Awesome one!

  • @AlmirVuk
    @AlmirVuk 4 роки тому +1

    This is great! Thanks Brian!

  • @md.khairulalam197
    @md.khairulalam197 3 роки тому +1

    Really useful...Thanks...

  • @beautifulheartsoothingreci28
    @beautifulheartsoothingreci28 4 роки тому

    But how is this possible? Why can't you just await a Task in a constructor, yet with the extension method you can?

  • @99MrX99
    @99MrX99 4 роки тому

    So you would suggest for events not making them async void, but normally void and in there calling an async method like shown in your video?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Yes, that is the purpose of this extension method. Anywhere you are forced to have an async void method that awaits a task, use this extension method instead. The most common places that will happen is in event handlers and commands

  • @algorithman2129
    @algorithman2129 4 роки тому

    Hi @Brian Lagunas (and everyone):
    I found some nearly identical TaskExtensions in System.Threading.Tasks. I do not know where they're coming from, my best guess is netstandard. The thing is, they have exactly your wording, but they are missing the async (e.g. public static void Await(this Task task, Action completedCallback, Action errorCallback) ). And they do NOT work as yours do.
    Brian, you have way more insight where this might come from, can you please tell them to fix it or to lose them altogether, because atm they do not wait.
    (Working on a netCore3.1 app and bringing my dialogs to life now)

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Hmmmm.... sorry, but I do not know anything about those extension methods. Are you sure those are in the framework and not in your project somewhere, or possible in a dependency you have? Put your cursor on the method and press F12. That will take you to the definition. You'll find out real quick where it lives. Don't look at the namespace, look at the assembly it is defined in.

    • @algorithman2129
      @algorithman2129 4 роки тому

      ​@@BrianLagunas I was completely off, sorry. They come from Prism 8.0.0.1740. Edit: Resharper did decompile it but without any clue which assembly its from.

    • @algorithman2129
      @algorithman2129 4 роки тому +1

      Don't bother Brian, my mistake. I had a slight misunderstanding. Sorry again.

  • @renatojr2010
    @renatojr2010 4 роки тому

    Excellent, I had a doubt and if I want to get the result of the Task how would I do it?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Then instead of Action, it would be Action completedCallBack. Then pass the value from the task to the callback. completedCallback?.Invoke(value);

    • @renatojr2010
      @renatojr2010 4 роки тому

      @@BrianLagunas
      Hi, I implemented following your idea but it is no longer an extension method, could you give me an example?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@renatojr2010 I don't understand. How is it not an extension method if you followed my code?

    • @renatojr2010
      @renatojr2010 4 роки тому +1

      @@BrianLagunas I was able to use Action as directed. Thank you.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@renatojr2010 I'm glad you figured it out

  • @SlowAside5
    @SlowAside5 4 роки тому

    Hi Brian. I have a tech question. Is it possible to implement an async ICommand? To my knowledge, this interface does not support async, but I've seen some discussion online on attempts to work around this. It is somewhat of a confusing topic and I would be interested to get your take on this. Thanks.

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Technically no. There is no such thing as an async command, because the framework only provides ICommand an its methods are invoked synchronously. Now, those "async commands" are just faking it to try and eliminate that scary async void method definitions. An AsyncCommand basically just lets you await a task method with some possible additional features like knowing if it's running, maybe cancel it, and maybe respond to completion or errors. There are other ways to handle Task methods for a command that doesn't involve creating a new command type.

    • @SlowAside5
      @SlowAside5 4 роки тому

      @@BrianLagunas Thanks for your response. What other ways are you referring to?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@SlowAside5 you could use the async in the delegate declaration, you could just do async void, you could use the extension method I showed in my video about async void just to name a few.

    • @SlowAside5
      @SlowAside5 4 роки тому +1

      Brian Lagunas I see, thanks. I think my confusion was over to how to execute an ICommand in a unit test when it had an async action in it. I ended up putting that action in its own method and then testing that method directly. I guess I will be skeptical about the need for AsyncCommand going forward.

  • @michaelalbaladejo6017
    @michaelalbaladejo6017 4 роки тому

    Thank you for this very interesting video.
    You say one of the async void problems is testability.
    I don't see how this method improves testability.
    How can the unit test wait for the Task?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      It improves testability because your methods no longer have to be async void. They can be of type Task, and unit tests can easily test a Task method. async void methods cannot be tested a you cannot await the result.

  • @andreikashin
    @andreikashin 4 роки тому

    Thanks, Brian. Now the next question - how to work with ConfigureAwait()?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Watch this video ua-cam.com/video/F9_8MJbsnzg/v-deo.html

  • @BurkusCat
    @BurkusCat 4 роки тому

    I think I watched a livestream of you adding similar extension methods to Prism a while ago? Are those available to use yet?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Those are available in the latest nightly builds of Prism v8.

  • @dracomalfoy1245
    @dracomalfoy1245 Рік тому

    very well explained, however I think it could have been made a little simpler by not using extension methods and Actions , since they are both off topic. Other than that great video!!. Thank you!!.

  • @markerickson9169
    @markerickson9169 4 роки тому +1

    Awesomely simple!

  • @merwintf
    @merwintf 4 роки тому

    Hey Brain! I was wondering if you have any github implementation, I was following up with your blog and you did mention the production code will be different! I just wanted to have a look at how things were implemented, if yes can you share the link to github repo may be?
    Great content btw
    Thanks.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Sorry, I didn't put this on github. I should probably start doing that. Thanks for the tip

    • @merwintf
      @merwintf 4 роки тому

      @@BrianLagunas Thank you and its very useful content , please let us know if you do though :)

  • @mauricibarth9503
    @mauricibarth9503 3 роки тому

    Why your videos haven't subtitles?

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      Because I can’t afford them 😁

    • @mauricibarth9503
      @mauricibarth9503 3 роки тому +1

      @@BrianLagunas I didn't know this is paid. I from Brazil, and it help me. Thanks for answer me.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      Thank you for supporting my channel

  • @MrTellus
    @MrTellus 4 роки тому

    Weird example. There is no async void in your code example but the one you created (the extension method). What about Task.Run(async () => await DoSomething()); in ctor instead?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      Maybe I didn't do a great job of explaining it. The point is to avoid async void methods. Usually when trying to use a task in a ctor, many make the task an async void method. This is bad. Instead, keep the method a task and still properly await the task, handle the completion, and handle any errors. I could have been more clear there. You sample would not accomplish the goal as you would still need to await the Task.Run which you can't do in the ctor. Not to mention that code is highly inefficient.

  • @makimupan4ur
    @makimupan4ur 2 роки тому +1

    I leave the super LIKE! It must sound as MONSTER KILL like in UT! SUPER LIKE!

  • @CezarWagenheimer
    @CezarWagenheimer 4 роки тому

    Will It block the UI or will run in a separate thread?

    • @BrianLagunas
      @BrianLagunas  4 роки тому +1

      It will not block the UI. If you were to take my sample and set the Text property to a value in the ctor after our DoSomething().Await() call, you will see that the ctor continues to run as expected while the task runs.

  • @mottahh4162
    @mottahh4162 4 роки тому

    isn't this similar to GetAwaiter().GetResult()?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      No, the GetResult will force your code to act synchronously and wait for the execution of the method call. Using my approach, your code will still fire async, but notify you when the task has completed. Plus, I would argue that you're not meant to use GetResult(). It's meant to be for compiler use only, not for you.

    • @mottahh4162
      @mottahh4162 4 роки тому +1

      @@BrianLagunas Thank you

  • @JeremySinclair
    @JeremySinclair 4 роки тому +1

    Whoa! So.... This was something very useful and I have places to use this already 🤔🤔

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      That's great to hear Jeremy! Thanks for watching

    • @BrianLagunas
      @BrianLagunas  4 роки тому +2

      Also, I didn't show it in the video, but keep in mind that you can actually return the Task result in your callbacks :)

  • @fmonteiropt
    @fmonteiropt 3 роки тому +1

    Code alien 👾, amazing !!

  • @muhammadwaqasaziz4054
    @muhammadwaqasaziz4054 4 роки тому +1

    You are awesome MAN!!!!

  • @pranabkumarde5634
    @pranabkumarde5634 3 роки тому

    hi Brian, your content was really helpful. Though I have one doubt. Below is one code which is returning "Data processing incomplete." when I call 'ProcessData'. If I am missing anything ? I appreciate your help. Thanks !
    class LongJob
    {
    bool _dataLoaded = false;
    public LongJob()
    {
    LoadDataAsync().Await();
    }
    public void ProcessData()
    {
    if (_dataLoaded)
    {
    Console.WriteLine("Data processing completed.");
    }
    else
    {
    Console.WriteLine("Data processing incomplete.");
    }
    }
    public async Task LoadDataAsync()
    {
    await Task.Delay(3000);
    _dataLoaded = true;
    }
    }
    static class TaskExtensions
    {
    public async static void Await(this Task t)
    {
    await t;
    }
    }

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      You didn't provide a callback in your Await method, so unless you wait over 3 seconds before calling your Process Data, the async call isn't complete yet.

  • @himanshugupta539_
    @himanshugupta539_ 4 роки тому

    I was using
    await task.Run()
    And calling my async task in that
    Also for errors
    Used .ContinueWith()
    And check if t.IsFaulted

    • @BrianLagunas
      @BrianLagunas  4 роки тому +4

      That can be problematic and very inefficient. Stephen Cleary has a great post series on Task.Run that explains this in detail.

  • @Unison_007
    @Unison_007 3 роки тому +1

    спасибо)

  • @yevheniytymchishin8401
    @yevheniytymchishin8401 4 роки тому

    It is possible to test "asyn void" methods via this library github.com/StephenCleary/AsyncEx
    Just do:
    AsyncContext.Run(() => ...your_async_void_action...);
    Assert.....

  • @shavais33
    @shavais33 3 роки тому

    I liked this video, but I wonder if is it effective to ask for subscriptions and likes at the very beginning of a video? I feel like that's sort of like asking for the sale before you've presented the product. I suppose if most of the people watching are existing followers, they're anticipating appreciating the content and just need reminding. I don't know, just a thought.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      Think of it like buying a movie ticket before you see the movie. Or buying a theme park ride ticket before you go on the ride. Except in this case, it actually doesn't cost anything at all 😁

    • @shavais33
      @shavais33 3 роки тому +1

      @@BrianLagunas So.. because the like button influences the UA-cam algorithm and thereby influences how many viewers you get which influences how much money you make, and since many people forget to press the like button if they wait until the end to press it even if they did like it, you want people to lie, or.. take it on faith they they will like the video, let's say.. and indicate that they like a video they haven't even seen yet.
      The like button IS NOT a ticket to watch. That's NOT its intent. Its intent is to act as an indication that the person pressing it liked the video. That's its intent.
      To me, content creators who are pushing this idea that it's a "ticket to watch" come off as greedy, pushy business people willing to bend the truth and maybe even be kinda just a bit bully-ish for the sake of their bottom line.
      I realize that trying to get financial traction as a YT content creator is a tough row to hoe, and I don't envy that position, and I appreciate the effort, but I think pressuring people to like and subscribe before they've even watched a video is going too far.
      It puts me in mind of how we used to have free TV, paid for by commercials. Cable sold us all on the idea of paying for TV with no commercials, so we all started paying money per month for it. Then they went and put all the commercials back in even though we were sold the idea of cable based on there being no commercials! I'm still chaffed about that. I canceled my cable TV service when they did that and I've never looked back. So now we have streaming services that have no commercials, that's great, but to get decent content you have to pay for multiple streaming services, which is just ridiculous.
      Anyway. No, sorry sir, but it's not a ticket to watch, it's a like button, and I don't press one unless something in a video inspires me to. However, as it happens - I did like this video, and I like you, actually, despite our disagreement about this, and I did press the like button on this page. =)

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      @@shavais33 Actually, you make some valid points. It's hard for creators to find a balance between playing by UA-cam rules and not coming off like a pushy salesperson. I will try an experiment. I will no longer ask for likes on my next few videos. I will then compare the number of likes on those videos to my past videos and see if there is a noticeable drop in likes. I still might ask for subs though 😁. I'm glad you enjoy my content, and thanks for your feedback. I appreciate you taking the time to help me improve my channel. Let's see how this experiment goes.

  • @AngusMcIntyre
    @AngusMcIntyre 3 роки тому

    People _need_ to stop saying that async void exceptions kill your process. They do not. They kill the work item on the thread. Your application keeps running.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      That's what they mean when they say that.

  • @charmerpppify
    @charmerpppify 4 роки тому +1

    Awesome!!!

  • @eeevans
    @eeevans 4 роки тому

    Great technique but not really async void. This was async Task called from non async method. What about async void called by the framework.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      Async void is when you would use this method. The framework does not call async void methods specifically. For example, a button click event handler. You would not make that async void because that's bad. Instead, you would use this technique to call the task async, but also be notified when the result has been returned. This allows you to keep your methods a Task and use them within other void methods that would otherwise be "async void". I probably could have done a better job of clarifying that point.

  • @peepeefrog_
    @peepeefrog_ 3 роки тому +1

    nice

  • @Stickman550
    @Stickman550 2 роки тому

    5:10
    I never thought an application crashing could be a good thing lol

    • @BrianLagunas
      @BrianLagunas  2 роки тому

      If something fails, you need to know about it

  • @andreikashin
    @andreikashin 4 роки тому +1

    That is digital magic

  • @paulp4061
    @paulp4061 3 роки тому

    You are still firing and forgetting your .Await() method from the constructor. If DoSomething() is part of the object initialization code then why does it keep running for another 3 seconds after constructor has exited? If an exception occurs in the initialization code it should cause constructor to crash but instead it lets the object to be created successfully and you can use it for the whole 3 seconds before it tells you (if you ask) that something went wrong. And it is still not testable.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      No. This is not fire and forget. Fire and forget is when you invoke the async method and there is no response. The method does its work and you have no idea about its results or of it ever completed. You can continue to use this object regardless of if an an exception occurred or not because the creation of the object is not stopped. The scenario you are using implies that this code is required for the object initialization. This may not always be the case. In those instances, this approach will help.

    • @paulp4061
      @paulp4061 3 роки тому

      @@BrianLagunas If it’s not required for the initialization then why is it being called from the constructor? And therefore, if DoSomething() fails then the constructor should fail, which it doesn’t. I faced this exact issues twice recently and in one case I ended up separating the slow initialization part into InitAsync() method which needs to be called manually after instantiating the object and then every other method that depends on it needs to check “if (_hasBeenInit)”, which is super ugly. In the other case I am calling Init synchronously from the constructor: InitAsync()/GetAwaiter.GetResult() which is also wrong for obvious reasons but at least it allows me to inject my class and be certain that it had been fully initialized. I wish there were a nicer way of doing it.

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      @Paul P There are many scenarios in which you want to run code that is not required for the object creation. Things such as analytics, messaging, loading initial data that may not be required for the class to function. While your specific scenario may not be a good use of this approach, there are many others than can benefit. Your scenario sounds like it would be better to have a factory asynchronously create your object instead. This way you can await the creation of the object.

  • @DoctorMGL
    @DoctorMGL 2 роки тому +2

    Genius Dayuuuuum son wp

  • @Po_Manfred
    @Po_Manfred 4 роки тому +1

    "Awesome"

  • @tcl78
    @tcl78 3 роки тому

    It is not clear to me why you couldn't just await the method in the constructor and why you had to introduce an extension to do that. Isn't it pretty much equivalent than awaiting the method in the constructor?
    I mean, isn't the extension method async too? Why don't you need to await it just the same as the original method?
    Also, the whole point of async/await was too get away from the callback hell, here you are reintroducing callbacks to make async work inside a constructor...

    • @BrianLagunas
      @BrianLagunas  3 роки тому

      As I explained in the video, you can't await a method in a constructor. This is a work-around for when you need to handle the completion of an async method in a ctor. You need the callback.

  • @danyelaristizabal
    @danyelaristizabal 4 роки тому +1

    Genius

  • @jakubsuchybio
    @jakubsuchybio 4 роки тому

    Nice short video, I like it.
    Buuuuuut
    Am I missing something? You are talking about problem with "async void", but from the start you are using "async Task DoSomething()"...
    What you are fixing is completely different problem than async void, isn't it?
    You are fixing fire&forget task. If someone would implement it like this. It's their job to handle errors inside DoSomething, when it is called as fire&forget (e.g. without await).
    If you want to never get into this problem, you can simply use "TaskScheduler.UnobservedTaskException" event and catch all these fire&forget exceptions there.
    Getting back to "async void" problem. If I recall correctly, the main issue with it is, that the exception thrown from that is not even catched with "TaskScheduler.UnobservedTaskException" event. Because without a Task, you can't save a call stack to that Task to be unobserved. So basically the only solution to "async void" is to try/catch the entire "async void" inside to get ever any handling of errors inside "async void"
    Am I wrong?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      I could have explained this better in the video, but when calling code in the ctor of an object, the common approach people take is to make the method async/void, but then they introduce all the problems I mentioned. Using the extension method, you can keep your method a Task and still call it within the ctor of an object, while handling the completion, the result, and any exceptions that may occur. Also, async void is often referred to as "fire and forget" but this isn't accurate. Async void methods can still block the caller if execution doesn't run into an await statement, and even then, it can still block the caller if the await call runs synchronously.

  • @2006lilmoe
    @2006lilmoe 4 роки тому

    GetAwaiter().GetResult() ?

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      No, the GetResult will force your code to act synchronously and wait for the execution of the method call. Using my approach, your code will still fire async, but notify you when the task has completed. Plus, I would argue that you're not meant to use GetResult(). It's meant to be for compiler use only, not for you.

    • @2006lilmoe
      @2006lilmoe 4 роки тому

      @@BrianLagunas it's for unwrapping the aggregate exception, which you'd want. If you're just "testing" then there's no issue in blocking. Event handlers should only be forwarding the events to proper async methods in which are tested separately. That's not duplication. Anyway, these workarounds are all unnecessary hacks that augment the flawed async implementation in .net framework. Should be fixed in core.

    • @BrianLagunas
      @BrianLagunas  4 роки тому

      @@2006lilmoe I agree this is an issue with it's implementation. Sometimes I wish this was never invented. I didn't have a problem doing the old way of async programming before this 😂

  • @auronedgevicks7739
    @auronedgevicks7739 9 місяців тому

    yeah .. no. This video is so wrong. "why async void" is bad (He is still using async void). "How do I await task in Ctor" (He is still not awaiting the task).

  • @soho1080
    @soho1080 Рік тому

    Worthwhile to ask if this only applicable to UI apps as the behavior isn't the same in Console apps.

  • @learner8084
    @learner8084 2 роки тому +1

    Great solution. Thanks.