0

This is my first attempt to get code to run async and I can't tell if it actually is. The function download report does not have an "await" and there is a warning saying it will run synchronously.

I am attempting to download multiple reports at the same time and then zip them all into one file.

The result is as expected but I would like to be certain that the code is actually performing in async.

static async Task Main(string[] args)
{
    string folderName = "Batch123";
    string fullDir = Path.Combine(ConfigurationManager.AppSettings["path"], folderName);
    Directory.CreateDirectory(fullDir);

    await RunReports(folderName);

    string zipPath = Path.Combine(ConfigurationManager.AppSettings["path"], "Zip", folderName);
    Directory.CreateDirectory(zipPath);
    ZipFile.CreateFromDirectory(fullDir, Path.Combine(fullDir, zipPath, "CRAs.zip"));           
}

private static async Task RunReports(string folderName)
{

    string[] dunsToProcess = new string[] {"d1"
                                            ,"d2"
                                            ,"d3"
                                            };

    await Task.WhenAll(dunsToProcess.Select(i => DownloadReport(i, folderName)));
}
private static async Task DownloadReroport(string DUNS, string folderName)
{
    NetworkCredential cred = new NetworkCredential(ConfigurationManager.AppSettings["networkUser"]
                                                    , ConfigurationManager.AppSettings["networkPassword"]);
    string fullPath = Path.Combine(ConfigurationManager.AppSettings["path"], folderName, string.Format("CRA for DUNS {0}.pdf", DUNS));
    WebClient wc = new WebClient();
    wc.Credentials = cred;
    wc.DownloadFile(@"http://xxxxxxx&pcDUNS=" + DUNS
                    , fullPath);
}

I hope it is right as it will be the basis of a lot of other changes. If not, can you point out what I am doing wrong.

Feel free to ridicule anything with my code!!! I have had no c# training at all.

Thank you.

Rand Random
  • 7,300
  • 10
  • 40
  • 88
KeithL
  • 5,348
  • 3
  • 19
  • 25
  • 2
    Just tagging your method as async doesn't make it do anything asynchronously. If you use HttpClient instead of WebClient there's an actualy Async method you can use for downloading and awaiting. – itsme86 May 07 '20 at 16:49
  • 2
    A good read - https://stackoverflow.com/questions/20530152/deciding-between-httpclient-and-webclient – Rand Random May 07 '20 at 16:50
  • 1
    all your code is running synchornously, but with a simple change replacing `wc.DownloadFile` with `await wc.DownloadFileAsync` will run async – Jesús López May 07 '20 at 16:51
  • @JesúsLópez - as itsme86 pointed out the `WebClient` doesn't use the `async/await` pattern – Rand Random May 07 '20 at 16:53
  • Documentation says the opposite https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfiletaskasync?view=netcore-3.1#System_Net_WebClient_DownloadFileTaskAsync_System_String_System_String_ – Jesús López May 07 '20 at 16:54
  • @JesúsLópez - so the method mentioned in the documentation returns an awaitable Task? – Rand Random May 07 '20 at 16:55
  • @RandRandom I linked the wrong method, I edited it and now is correct – Jesús López May 07 '20 at 16:56
  • @JesúsLópez - just noticed that you didn't provide an URL for `DownloadFileAsync` but for the montrosity `DownloadFileTaskAsync`, didn't know that they did a seperate method that returns an `Task` sorry my bad – Rand Random May 07 '20 at 16:58
  • @RandRandom, yes I was confused at first too. – Jesús López May 07 '20 at 17:00
  • 1
    Consider adding logs like Console.WriteLine("Download Starting: "+DUNS) and Console.WriteLine("Download Finished: "+DUNS) before and after the download code and you will see when it async and when it is not. – Felipe Faria May 07 '20 at 17:03
  • Thank you. I really appreciate all of this! – KeithL May 07 '20 at 17:03
  • @JesúsLópez Well... Making your suggested change brought the time from 2 minutes to process 50, down to 8 seconds! I CAN tell it works now! – KeithL May 07 '20 at 17:53

1 Answers1

-2

I believe you are referring and threads and tasks and trying to find something async.

As First, I am not sure what you are doing and how this even works when your main method is Task, this make no sense to me, so, try following :

  1. let main to be as this is default, there is nothing to do in this declaration change
  2. made class which is doing what you want to do (downloads probably)
  3. then made Tasks or threads to call many tasks or threads in time. Keep in mind that there is no point to made to many of them, you may want to limit number of tasks/threads executing in time. You may want to have all tasks identified, or you may want just to wait for all of them to be executed, your need and decision, but Task have properites IsCompleted, IsCanceled, etc ... and if you are generating threads you may want to investigate following classes and methods :

ManualResetEvent WaitHandle

As short resume, you approach is wrong if I am even able to understand what you are trying to do in this code

Gedza
  • 1
  • 2