繁体   English   中英

C#异步任务等待vs等待

[英]C# Async Tasks wait vs await

有一段时间让我感到困扰,有些事情我无法理解。

我已经定义了从Facebook API提取信息的工作流,基本上我有3个不同的async tasks

执行报告

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
}

监控报告

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
}

这是主要任务,其中调用了所有其他方法

 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);
}

我在此foreach循环中调用我的Main任务,这就是发生问题的地方。

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);

我不明白为什么foreach循环为什么不继续使用await控制台应用程序突然关闭,不应该等任务完成后再await “ wait”,然后继续执行下一行代码?

我已经解决了将所有任务放入列表并等待所有任务的问题,但是我想对此进行解释。

[编辑]对问题进行了编辑,以创建一个最小的可复制示例。

当您在方法中使用await关键字时,它将被挂起,并将控制权交还给async方法的调用者,直到完成async方法中的工作为止。 在控制台应用程序中,主线程将完成其工作,因此程序将退出。

以以下程序为例:

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

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

该程序将立即退出,因为Main线程不await DoWork异步方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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