有些东西让我烦恼了一段时间,在我的代码中发生了一些我无法理解的事情。
我已经定义了一个从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
循环中调用我的主任务,这就是问题发生的地方。
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
&#34 ;等待&#34;直到任务完成,然后继续下一行代码?
我已经解决了将所有任务放入列表并等待所有问题的问题,但我想解释一下。
[编辑] 编辑问题以创建一个可重复性最小的示例。
答案 0 :(得分:1)
当您在方法中使用await
关键字时,它会被暂停并且控制权将返回给您async
方法的调用方,直到等待方法中的工作完成为止。在控制台应用程序中,主线程将完成其工作,因此程序将退出。
以下列程序为例:
class Program
{
static void Main()
{
DoWork();
// Will exit immediately
}
static async Task DoWork()
{
await Task.Delay(10000);
// Should wait 10 seconds
}
}
此程序将立即退出,因为主线程没有await
DoWork
异步方法。