C# Advanced Async – Getting progress reports, cancelling tasks, and more

38
5



Now that we know how to do the basics in async, let’s take it to the next level. In this video, we look at how to get status reports back from asynchronous tasks so we can display a progress bar and more to the screen while they are running. We also set up the ability to cancel a long-running or hung asynchronous task.

We will also explore the differences between adding tasks in a foreach loop vs Parallel.foreach and how we can even get the benefits of both methods at the same time.

Newsletter signup (with exclusive discounts): (your email will be kept safe and you will not be spammed).
Source Code:
Intro to Async / Await:

Nguồn:https://wijstaanvooronzegrondrechten.org/

38 COMMENTS

  1. Hi Tim. Tks, great video.
    In the method RunDownloadParallelAsync, I think you can use Task.WhenAny and for each task complete report the progress.

    public static async Task<List<WebsiteDataModel>> RunDownloadParallelAsync(IProgress<ProgressReportModel> progress)

    {

    List<string> websites = PrepData();

    List<WebsiteDataModel> output = new List<WebsiteDataModel>();

    List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();

    ProgressReportModel report = new ProgressReportModel();

    foreach (string site in websites)

    {

    tasks.Add(DownloadWebsiteAsync(site));

    }

    while (tasks.Any())

    {

    var taskFineshed = await Task.WhenAny(tasks);

    output.Add(taskFineshed.Result);

    report.SitesDownloaded = output;

    report.PercentageComplete = (output.Count * 100) / websites.Count;

    progress.Report(report);

    tasks.Remove(taskFineshed);

    }

    return output;

    }

  2. Good video. I just wrote a static TaskThrower component using some of this… it schedules IThrowableTask with built in callback support to make life easy for the caller. Since it is designed for an app that allows runtime editing/compilation of gameobject scripts, it also handles cross-Application Domain. This allows me to see my gamecode changes in real time. Another component handles the cross-domain stuff and tears down stale app-domains when code has changed.

    c# is worryingly easy! It's a bit scary, teetering about on top of such a vast framework – I like implementation details.

    I welcome less typing, but it leaves me feeling like less of a coder and more of a framework jockey : / I hope that feeling wears off.

  3. What is the main different between await and wait as in Task.Wait(). I noticed when I use Task.Wait() on my UI thread it blocks it forever, but I am not sure why.

  4. Hey Tim,
    Can you explain, that if you run these tasks parallel, why it gives you always the same output?

    I mean, I would really like to see a continuation, where the results are printed as they come in. lets say cnn finishes last, then next iteration wikipedia is the last….

    Or, if I miss something, can you point out why you have always the same order of sites there? How would you modify the code, so you see the items in finishing (occasionally random) order.
    Great video, keep it up.

  5. Hi Tim,
    Thanks for this great video ! Just a quick question – why is it always slower on the first run, then faster afterwards ? Could you provide more details on whats going on ?

  6. Hi, I may not be seeing the code flow correctly or overthinking this but how are how can we use the progress.ProgressChanged += ReportProgress event/event handler before we pass progress to RunDownloadAsync? I will continue to review and it will probably click. Does it have something do with ProgressReportModel is a reference type so we have access to that same object information.

  7. In executeAsync you PrintResults once after you've awaited for all results and you also PrintResults when the progressChanged event is fired…why is that

  8. Hi Tim, another great video. It is very helpful, thanks for your work and time! How many tasks can we execute at a time? In your case there are several sites, but if this list of sites will be much larger e.g. 1000 sites, should we limit a number of concurrent tasks? I know task not a thread, but resources are limited anyway:) So my question is: how to know how to limit concurrent tasks?

  9. Thank you, Tim. Another great video.

    I have a question that I don't know if it is solved because of the difference between Tasks and Threads that you mention in previous comments.

    My question is: In the Parallel.ForEach, when you refresh the report information inside (Sites and Percentage). Could there appear concurrency problems due to multithreading? In other words: Can you update a shared variable inside the Parallel.Foreach without concurrency issues?

  10. Great video. Thank you. One question – can the IProgress/Progress types be passed across a WebApi call (and work to report progress back to the client)? When I pass it (Progress object) through a PostAsync call the object ends up  ends up being null, but it is not right before I make the call

  11. Tim, thanks for the great video. It was very helpful. I seem to be having an issue when adding the execution time to the window for the async execution. It seems as though after the time is added to the text box, the ReportProgress method is called one last time and writes over the results. The issue doesn't happen when you cancel the operation though. I did download your source code an have it copied exactly, but I used a WinForm instead to implement it. What do you think the cause for this would be? Are there some weird async rules for WinForms that aren't present in WPF projects? Thanks!

  12. This is a great video, thank you very much for making it! This one and its predecessor https://www.youtube.com/watch?v=2moh18sh5p4 have helped me to greatly understand the concepts of asyn/await. However, I am getting an issue at https://youtu.be/ZTKGRJy5P2M?t=2840 , in that sometimes the code runs just fine and occasionally I get a System.InvalidOperationException
    : Message=Collection was modified; enumeration operation may not execute. Some searching on this in conjunction with Parallel.ForEach brings up results of using .Open() or .OpenPartial(). @IAmTimCorey is possible you could make a 3rd installment that addresses what these methods do and/or how to utilize them with regards to Parallel?

    Thanks again – very informative!

  13. Hi, thanks for the such a nice tutorial on async await task, really give lot concept over it.
    I have one question to ask on this topic is that, can we use the async and await task concept in WebApi, if yes then, what is the benifit we get from it. And if no then why?

  14. First of all, your videos are amazing! Thank you so much for your great work!

    I have a problem with the progress section: I implemented your code line by line, the progress bar works great in the asyncronous method and the list of downloaded sites is updated accordingly. Anyway, it seems that the last websites is never "awaited" and the code proceeds to the commands watch.Stop(), elapsedMs = … , and Text+= $"Total execution time: …" (but actually that's not written)
    Only at the end, the last website alerts the progress, and the info about it are added to the textbox (PrintResults clears at first the whole textbox so any info about the total execution time is erased)

    The final result is that I never see the final string with the "Total execution time" in the textbox, but I see all the websites and the progressbar full.
    PS the code about Async Execution works correctly without progress, and I can see both the list of websites and the total execution time… any idea?

    Thank you again Mr.Corey

  15. Can you make a video where you go into detail about Synchronization Context and when/when not to use .configureAwait and the optimization benefits of it.

LEAVE A REPLY

Please enter your comment!
Please enter your name here