How to Report Progress with Async/Await in .NET Core 3

Поделиться
HTML-код
  • Опубликовано: 19 окт 2024
  • In this video, we learn how to report progress with async/await in .NET Core 3. If you're using async await, chances are you have long running processes executing on different threads. However, it's very common to update the user on the current progress of that operation in the UI. Maybe you are downloading or uploading files to a server. Perhaps you are copying a number of files from one location to another. Whatever your reason, reporting the progress of an async await process is very easy.
    Start by having your method doing the work report the progress using the IProgress(OfT) interface. This interface allows you to report the progress of your method when using async await. It may look something like this:
    void LoopThroughNumbers(int count, IProgress(ofInt) progress)
    {
    for (int x = 0; x (lessthan) count; x++)
    {
    Thread.Sleep(100);
    var percentageComplete = (x * 100) / count;
    progress.Report(percentageComplete);
    }
    }
    Now that your method is reporting the progress of its operation, you can now respond to that progress report and display it to the user. Start by creating a new Progress(ofT) object and provide your handler as follows:
    var progress = new Progress(ofInt)((value) =(greaterThanBracket)
    {
    _progressBar.Value = value;
    _textBlock.Text = $"{value}%";
    });
    Once your progress handler is in place, you can now pass this to your method being run in a task to report the progress of your async await method.
    await Task.Run(() =(greaterThanBracket) LoopThroughNumbers(100, progress));
    That's it!!! You're all done.
    Bonus Tip: Don't use Task.Run in the implementation of a method; instead, use Task.Run to call the method.
    Check out my new Pluralsight course "Introduction to Prism for WPF":
    pluralsight.px...
    Sponsor Me:
    github.com/spo...
    Follow Me:
    Twitter: / brianlagunas
    Twitch: / brianlagunas
    Blog: brianlagunas.com
    GitHub: github.com/bri...

Комментарии • 131

  • @rogerpence
    @rogerpence Год назад +2

    It me four hours to find this superb 7 min solution. Thank you, Brian.

  • @DoctorMGL
    @DoctorMGL 5 месяцев назад +1

    why you are soo good at teaching ? dayuuum
    i swear i'm not just complimenting you , your teaching method is clear and straight to the point
    which is something we often miss IRL in schools, and also online .

    • @BrianLagunas
      @BrianLagunas  5 месяцев назад

      Thank you so much for the kind words. I appreciate you

  • @kristynoble8848
    @kristynoble8848 2 года назад +3

    Exactly answered my question, and in only 7 minutes. Clear, concise, and simple. I wish all example videos were this clear. Thank you * 1000!

  • @Rubiole
    @Rubiole Год назад +3

    This is such a nice explanation and relatively easy to follow! Thanks for your contribution to the community

    • @BrianLagunas
      @BrianLagunas  Год назад

      Thank you so much for the kind words

  • @bartsworkshop
    @bartsworkshop Год назад +1

    Thank you, this is the most simplistic way of showing progress that i found so far. Please make more videos like this they are awesome!

    • @BrianLagunas
      @BrianLagunas  Год назад

      Thank you so much for the kind words. I want to make more videos, I just haven’t had time. My day job is very demanding.

  • @tommyseacat3580
    @tommyseacat3580 2 года назад +1

    Wow, super video. This concept was on a coding interview home exercise and I didn't know how to report. THANK YUUUUU

  • @TheBishopOfBarton
    @TheBishopOfBarton 2 года назад +1

    Just found this today - what a simple to follow and very helpful tutorial - just implemented the principles in a piece of code and it worked. Thank you!

    • @BrianLagunas
      @BrianLagunas  2 года назад

      Awesome! Great to hear! Thanks for watching

  • @vinodcs80
    @vinodcs80 5 месяцев назад

    such a complicated concept taught so easily, wow, appreciate it

  • @longuinni
    @longuinni 4 года назад +3

    Great as always. The next episode could be about the cancelationToken. The user start a task but before finish he decides to cancel that task.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      That's a good idea! Thanks for sharing

  • @kylerbriskey372
    @kylerbriskey372 3 года назад +2

    Amazing. Simple solution and with the aync await, it cleared up my window studder. Thanks!

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      Great to hear! Thanks for watching

  • @kayun-chan-pit8642
    @kayun-chan-pit8642 4 года назад +1

    Greatest example ever. Extremely clear. Let me bow my head for you 3 times. Thank you very much.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Thank you so much for the kind words. Thank you for watching

  • @Zonawanialonnua
    @Zonawanialonnua 4 года назад +1

    Again, everything is very simple.
    And as you know, everything simple is brilliant!
    Thanks Brian!

  • @haroldpepete
    @haroldpepete Год назад

    you have a new subscriber, by the way let me tell you that you do a great job explaining net.core easy and straight to the content

  • @NickBullCSharp
    @NickBullCSharp 4 года назад +1

    Fantastic video again Brian. This couldn't have come at a better time as I'm attempting this exact thing at work now to improve user experience :)
    Also great Key point about Task.Run(). I have the habit of putting a Task.Run in the method implementation. Therefore, thanks for the heads up on that one! :D

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Thank you very much for watching.

  • @MRJerrod410
    @MRJerrod410 10 месяцев назад

    Is there something special about Progress that that allows it to update the controls on the UI thread or will any lambda function created on the UI thread hold the thread it was created on in it's closure?

  • @pleilleur
    @pleilleur 2 года назад +1

    Great explanation, very useful 👍Thanks

  • @julianturner6203
    @julianturner6203 4 года назад +1

    Thanks Brian, you got the best content right now. You are the best

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Thank you very much for the kind words.

  • @dayta2137
    @dayta2137 2 года назад +1

    Excellent content. Short and sweet! Thanks a lot.

  • @udaysuddhala3512
    @udaysuddhala3512 4 года назад +1

    Very clear explanation !! Loved it👌

  • @ПавелАлексеев-р7и
    @ПавелАлексеев-р7и 2 года назад +1

    Thank for this video, its very simple but usefull for work !! )

  • @fernando.jimenez
    @fernando.jimenez 4 года назад +5

    Maybe it's just me but I've noticed in your latest videos that the audio/video are not in sync.
    Great video btw. Thank you.

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Yeah, this is a known issue with RUclips. It works fine on some browsers/devices, and the audio is out of sync on other devices/browsers. I've seen this on my Android while it works perfectly on my Desktop. I am not sure how to prevent that from happening.

    • @GiovanniQuarella
      @GiovanniQuarella 4 года назад

      @@BrianLagunas but with your youtube video from twitch it doesn't happen.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Yeah, its very weird. I tried some different settings on my next video which will be released tomorrow. Hopefully these new setting will fix the problem. Let me know

  • @rodrigocaballerohurtado5367
    @rodrigocaballerohurtado5367 4 года назад +1

    So simple to understand now

  • @vaibhavverma7440
    @vaibhavverma7440 2 года назад +1

    perfect answer to my question!

  • @mojizze
    @mojizze 4 года назад +1

    Wow! Best explanation I've seen. Thanks a lot

  • @abosqr7029
    @abosqr7029 4 года назад +1

    Thank you so much, this is very useful and easy to understand.

  • @DaviBittencourt
    @DaviBittencourt 4 года назад +1

    Great Brian!! Waiting for more ...

  • @septimusseverus252
    @septimusseverus252 2 года назад +1

    I can't thank you enough for this great video

    • @BrianLagunas
      @BrianLagunas  2 года назад +1

      Thank you so much for watching

  • @VinuP2023
    @VinuP2023 4 года назад +1

    As usual, awesome explanation :)

  • @alhassanmarafa8460
    @alhassanmarafa8460 3 года назад

    Hi Brian, this is the best video i have seen about this subject, Thank you. i have one question though. if i choose let's say count = 5,
    the progress will not go till the end of the bar which i assume is not what we want. No matter the count we should get 100%. Any idea?

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      The math in that demo already handles that scenario. The only thing you'll need to do is set the final 100% state when the task has completed since the progress will not be reported on task completion.

    • @alhassanmarafa8460
      @alhassanmarafa8460 3 года назад

      @@BrianLagunas Thanks for the quick reply. I will see how i can manage that. I'm kinda new to this.

  • @raulands
    @raulands 4 года назад +1

    Brilliant, thanks Brian 👍🏻

  • @francisroshanfernando9806
    @francisroshanfernando9806 3 года назад +1

    you saved my day !!! super

    • @BrianLagunas
      @BrianLagunas  3 года назад

      Great to hear! Thanks for watching

  • @user-mr-m12312
    @user-mr-m12312 4 года назад +12

    So my question is: how can I become as cool as Brian Lagunas? :)

    • @BrianLagunas
      @BrianLagunas  4 года назад +2

      HAHAHA!!! You're way cooler than me.😀

  • @aldoboell
    @aldoboell 3 года назад +1

    awesome, thats what I needed.

  • @goodstas
    @goodstas 2 года назад

    Thank u for your videos. I have a question. Usually if we work with a threads then you can set any Control only from UI thread. Here u used Progress class which are invoked through a SynchronizationContext instance captured when the instance is constructed and in your example this is UI thread. So in case if we were using different class, it won't work. Am i right?

  • @JesusAnguloGasco
    @JesusAnguloGasco 4 года назад

    Great video Brian!

  • @mfelipeof
    @mfelipeof 3 года назад

    Awesome video Brian, thank you so much for this !!
    Just one tip about your rule: "Do not use Task.Run in the implementation of the method...": Some situations, like using a nuget package that performs async operations or creating a custom nuget package to use accross many projects, is required return tasks objects and the consumer project use the "await" keyword.
    One additional question is: How can I report progress when execute a external .exe or any command line, using Process class ? In this case, I don't have a loop or anything like this, you know? The command line can perform a looong time to complete. I can estimate a duration of the command, but I don't know how update the progress bar while the time is passing. I think that is something like a "tick" check in a async task

    • @iankirkpatrick2022
      @iankirkpatrick2022 Год назад +1

      In order to show a meaningful progress bar, you need an end goal... how long should it take. If the exe you're executing doesn't give you a way to know that you have no way of calculating a percent cause there's nothing to compare current progress to. You're stuck with exactly what you are doing... an estimation based on what you normally see it take. For this reason, you either have to make up an end goal or don't bother with a progress bar cause it'll probably be meaningless to the user.
      In other words, if the external process doesn't report progress, you are limited in what you can report. It's a black box.

  • @tkshiv20
    @tkshiv20 3 года назад +1

    Thank you so much.

  • @CHITRANSHSHARMA
    @CHITRANSHSHARMA 3 года назад

    Thanks, I used similar in .net framework

  • @senadmeskincoding
    @senadmeskincoding 4 года назад

    Is it me or the last few videos have an audio delay?
    Good explanation by the way. Great video.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Yes, some people have seen an audio delay, but I am unable to. It's really weird and frustrating on my part. I am trying to figure out what could be causing the issue. It's the never ending "it works on my machine" LOL

  • @NK-xw4uu
    @NK-xw4uu 3 года назад

    Brian, please can you clarify whether this approach (passing IProgress) of updating progress bar is specifically when we use async/await with Task.Run? Where as if I had used async/await without Task.Run (say for couple of io bound operations in a for loop) then I could directly update the progress bar value (because it's all happening on the same thread)?

    • @BrianLagunas
      @BrianLagunas  3 года назад

      Correct. If you have a task method that reports progress, using calling Task.Run isn't required.

  • @sarthakchauhan4163
    @sarthakchauhan4163 4 года назад +1

    Great video

  • @matteobarbieri2989
    @matteobarbieri2989 4 года назад +1

    I've always used BackgroundWorker and Report progress event. Is the behavior different?

    • @BrianLagunas
      @BrianLagunas  4 года назад +2

      Background worker is the "old way" of doing background tasks and reporting progress (which still works). If you're using the newer async/await approach, then this is how you would do it.

  • @osman3404
    @osman3404 4 года назад

    I have similar code in my WPF apps but was wondering if the method LoopTheoughNumbers() was doing an IO bound async task, would it still be “best practice” to call it with the Run.Task() ?
    Tkx again Brian

    • @BrianLagunas
      @BrianLagunas  4 года назад

      You want to use Task.Run to call CPU-bound methods only

  • @PeterKellner99
    @PeterKellner99 4 года назад

    Hi Brian, I've always wanted to do this. Thanks! I'm just wondering though, at the end, when you did your victory dance by grabbing the title bar and dragging it all over you screen, what were you actually demonstrating by doing that? I already believed the the windows async manager works properly. :). Maybe if you pressed a cancel button, then I would have been impressed. Wait, was there a cancel button?

    • @BrianLagunas
      @BrianLagunas  4 года назад

      I was demonstrating that the UI is not being locked up or blocked by the reporting of the progress that is being reported from the long running task. The UI is remaining responsive during the entire process of running the task and updating the UI with the reported progress. There was not a cancel button. Maybe I should add one :)

  • @DarkSolidity
    @DarkSolidity 2 года назад

    If my code looks like this how would I report progress?
    using (HttpRequestMessage request = new HttpRequestMessage(method, uri) {
    HttpClient client = new HttpClient();
    Task task = client.SendAsync(request);
    HttpResponseMessage response = await task;
    I’ve noticed that when defined like this I don’t have access to task.Run()
    I see task.RunAsynchronousily though
    I’ve been trying to adapt several progress reporting methods but I haven’t been able to get any of them to work.

  • @diegoronkkomaki6858
    @diegoronkkomaki6858 4 года назад +1

    Great!

  • @julianturner6203
    @julianturner6203 4 года назад +1

    Brian, can you please tech us how to copy a lot files with sub directories without blocking the UI? Thanks in advance

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      That might make for a good video 😀

    • @julianturner6203
      @julianturner6203 4 года назад +1

      @@BrianLagunas that would be awesome 😁

    • @BrianLagunas
      @BrianLagunas  4 года назад

      @@julianturner6203 Here you go ruclips.net/video/8PLlHDfN-ew/видео.html

  • @sleepingtiger4436
    @sleepingtiger4436 2 года назад

    I need an explanation on why it is inefficient? Please explain the "Do not run the task.run in the implementation oof the [async] method"???

  • @knlreiniger
    @knlreiniger 3 года назад +1

    I have a problem; the progressbar only updates at the end of the method.
    It is worth to mention that the method im trying to run async is located in a seperate cs file.

    • @knlreiniger
      @knlreiniger 3 года назад

      tried moving the method to the xaml.cs file where the caller is located ,still not working

    • @knlreiniger
      @knlreiniger 3 года назад

      nevermind, was my own stupidity, i forgot to put thread sleep, apparently it goes too fast to update :D

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      Awesome! I am glad you figured it out.

    • @MJ-xl5jz
      @MJ-xl5jz Год назад

      I had that problem with the Textbox. Then I just called .Update at the Textbox right after the change to the .Text Property.

  • @rahulmathew8713
    @rahulmathew8713 4 года назад +1

    Hi Brian,
    Can you please do a video on creating a user control with dependency property, routed event and to implement commanding with a user control.
    How to attach a command to handle click event with a user control.
    Thanks
    Rahul Mathew

    • @BrianLagunas
      @BrianLagunas  4 года назад

      That's a lot for one video. These would have to be broken down into separate videos. Also, it sounds like you should probably be using a Custom Control not a UserControl.

    • @rahulmathew8713
      @rahulmathew8713 4 года назад

      @@BrianLagunas Hi Brian, I am watching your plural sight. So in that, the course title is given Custom Control. So should I follow that one. Is there is a difference between custom and user control?
      Please advise
      Thanks
      Rahul Mathew

    • @BrianLagunas
      @BrianLagunas  4 года назад

      @@rahulmathew8713 Yes there is a difference. I believe I talk about those differences in the course. Thanks for watching :)

  • @gus9822
    @gus9822 4 года назад +1

    Hi. i am loving your videos . Big fan . I have a question regarding "DialogAware". How do i know if a dialog i already open? I don't want to open a dialog 2 times . There is way to ask the dialog service?
    Thank you

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Thank you for watching. It sounds like you'll need to create a custom dialog service that derives from the Prism service, and add the ability to track your dialog instances.

  • @microtech2448
    @microtech2448 2 года назад

    How would you do same thing when it is . Net core mbc application and you are uploading large excel file and this file is being processed on separate class library project called from mvc controller? Show progress bar in real time?

    • @BrianLagunas
      @BrianLagunas  2 года назад

      Since it doesn’t sound like your upload method supports reporting progress, you’ll just show an indeterminate progress bar when you start the upload and close it when the upload completes.

    • @microtech2448
      @microtech2448 2 года назад

      @@BrianLagunas Thanks for confirmation

  • @cueware
    @cueware 3 года назад

    Hi, thanks for your Video. How I can do that with DI Containers?

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      I'm sorry, but I don't understand the question. Do what exactly with a DI container? Can you provide more detail?

    • @cueware
      @cueware 3 года назад

      @@BrianLagunas Thanks for your answer. I mean Dependency Injection Containers like Autofac, Ninject etc... How can i access the Progress Class on the calling class when autofac is automatically injecting the Progress Class? Sorry 4 my bad english...

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      Usually you'll register your service class with the container and then the container would automatically inject that service class into the ctor of the class your trying to use it in. Also, don't worry about your English. Its great! I envy anyone that can speak multiple languages.

    • @cueware
      @cueware 3 года назад

      @@BrianLagunas Hello thank you, do you think a video about this would be helpful for many of your followers? I am currently trying to get closer to the solid principles

    • @BrianLagunas
      @BrianLagunas  3 года назад

      I could probably do a video series on the SOLID design principles. Great idea!

  • @harsheng
    @harsheng 4 года назад +1

    How to debug Task and threads in better way in c#?

  • @ievheniiierokhin1677
    @ievheniiierokhin1677 4 года назад

    Hm but whats wrong with wrapping implementation of method with task.run, i did it a lot and just like await MyMethod() and i am happy with that, why its better to wrap synchronous method within task.run?

    • @BrianLagunas
      @BrianLagunas  4 года назад +2

      Here's a great blog post by Stephen Cleary that explains the issue with Task.Run in the method implementation very well: blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html

    • @ievheniiierokhin1677
      @ievheniiierokhin1677 4 года назад +1

      @@BrianLagunas thanks, great post!

    • @janhendrikschreier
      @janhendrikschreier 4 года назад

      @@BrianLagunas Maybe that whole story is worth a video in itself. Steven refers to ASP.net most of the time, so I focussed example might be worth it. At least for me I just got rid of a sexy busy indicator which is replaced by data just being there synchronosly, bamm!
      So my question would be, if there is some sort of natural tipping point, where you suggest to go async because it is too slow or is it pure try and error when you switch over?

    • @BrianLagunas
      @BrianLagunas  4 года назад

      @@janhendrikschreier I always place the loading of data on a worker thread in my desktop apps. My #1 rule is to keep the UI responsive at all times. Considering the various numbers of unknowns of the end-user system (RAM, processor, cache size, etc), I don't take a chance.

  • @magicsmoke0
    @magicsmoke0 4 года назад +1

    Feels like events are used less and less now.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Technology keeps making things easier for us.

  • @MrJohn2475
    @MrJohn2475 3 года назад

    does this work on ASP.NET?

    • @BrianLagunas
      @BrianLagunas  3 года назад

      There may be some differences, but in general it should work.

  • @justinyoung4826
    @justinyoung4826 2 года назад

    Unhandled Exception: explicit use of "pretty cool right?" belongs to StyroPyro lol

    • @BrianLagunas
      @BrianLagunas  2 года назад +1

      I’m guessing that’s another RUclipsr that says that a lot? 🤣

    • @justinyoung4826
      @justinyoung4826 2 года назад +1

      @@BrianLagunas Yes, it's his main catch phrase, but I wasn't being serious at all, just trying to crack a joke in the comments. I appreciate your work man, and your video have been very helpful to me.

  • @TSHORYUKEN
    @TSHORYUKEN Год назад

    but how to update progress from a specific task like API resquests/ long running task ???

    • @BrianLagunas
      @BrianLagunas  Год назад

      If the API doesn’t provide a way to report progress you’ll have to use a non-deterministic progress indicator.