简体   繁体   中英

C# Async Tasks wait vs await

There is something that is bugging me for a while, something that happen in my code I can't understand.

I've defined a workflow to extract information from the Facebook API , basically I have 3 different async tasks .

Execute Reports

private static async Task<List<DataTypes.ReportRun>> ExecuteMarketingReports(FacebookClient fb, List<DataTypes.Request.Batch> batch_requests)
{
//Do stuff - Make async POST requests to 
//FB to execute reports on FB server side
}

Monitorize Reports

private static async Task<List<DataTypes.AdReportRun>> MonitorizeMarketingReports(FacebookClient fb, List<DataTypes.ReportRun> tListReportRun)
{
  //Do stuff -- Check if the reports are ready or not, and return a list with status
}

GetReportData

private static async Task GetReportData(FacebookClient fb, List<DataTypes.AdReportRun> tListReportRun, DateTime since, DateTime until, string breakdown)
{
//Do stuff -  Gets report thata once the reports are finish and create the files
}

This is the main Task where all the other methods are called

 private static async Task PullInsightsData(FacebookClient fb, List<DataTypes.Request.Batch> batchRequests, DateTime since, DateTime until, string breakdown)
{
    var tResult = new List<DataTypes.AdReportRun>();
    int retry = 0;
        List<DataTypes.AdReportRun> tReportCompleteList = new List<DataTypes.AdReportRun>();
        List<DataTypes.AdReportRun> tReportIncompleteList = new List<DataTypes.AdReportRun>();


        var report_ids = await ExecuteMarketingReports(fb, batchRequests);
        Thread.Sleep(20000); // Waits 20 seconds before get the info.
        do
        {
            /*Start monitorizing the reports*/
            var tReport_info = await MonitorizeMarketingReports(fb, report_ids);

            /*Get the reports that are complete*/
            tReportCompleteList = tReport_info.Where(x => x.async_percent_completion == 100).ToList();

            if (tReportCompleteList.Count > 0)
                 await GetReportData(fb, tReportCompleteList, since, until, breakdown);

            tReportIncompleteList = tReport_info.Where(x => x.async_percent_completion < 100).ToList();

            report_ids = (from x in tReportIncompleteList
                          select new DataTypes.ReportRun { report_run_id = x.id }).ToList();

            var sleepTime = TimeSpan.FromSeconds(Math.Pow(2, retry + 1));
            Thread.Sleep(sleepTime);
            retry++;
        } while (report_ids.Count > 0 && retry < 8);
}

I call my Main task in this foreach loop, and this is where the problem occurs.

for (int i = 0; i < ActiveAdAccounts.Count; i = i + 50)
{
    var AdAccountsSubList = ActiveAdAccounts.Skip(i).Take(50).ToList();

    var batchRequests = ....

await PullInsightsData(fb, batchRequests, (DateTime)since, (DateTime)until, breakdown.Replace(",", "_"));
    //tTaskList.Add(PullInsightsData(fb, batchRequests, (DateTime)since, (DateTime)until, breakdown.Replace(",", "_")));   
}
//Task.WaitAll(tTaskList);

I don't understand why the foreach loop does't continue using the await the console application closes suddenly, shouldn't await "wait" until the task is finish and so then proceed to the next line of code?

I've solved the problem putting all the tasks into a list and waiting for all, but I would like an explanation for this.

[EDITED] Question was edited to create a minimal reproducible example.

When you use the await keyword in a method, it is suspended and the control is given back to the caller of your async method, until the work in the awaited method is done. In a Console Application, the Main thread would finish its work so the program will exit.

Take for example the following program:

class Program
{
    static void Main()
    {
        DoWork();
        // Will exit immediately
    }

    static async Task DoWork()
    {
        await Task.Delay(10000);
        // Should wait 10 seconds
    }
}

This program will exit immediately, because the Main thread does not await the DoWork async method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM