来电者:
var snapshotMessages = snapshotRepository.GetMessages();
_ = Console.Error.WriteLineAsync("Loading XML timetables...");
// some lengthy operation which loads a large dataset from a SQL database
await foreach (var item in snapshotMessages) {
// process the item
}
被叫者:
public async IAsyncEnumerable<Pport> GetMessages() {
Console.Error.WriteLine("Start getting messages");
var timestamp = DateTime.MinValue;
// some code which start downloading a large file from FTP
}
我想并行数据库加载和下载。但是,“开始获取消息”行没有出现,这表明程序没有像我预期的那样并行运行。
文档说:
异步方法同步运行,直到到达第一个等待表达式,此时该方法将挂起,直到等待的任务完成。与此同时,控制权返回到方法的调用者,如下一节中的示例所示。
这在这里似乎不是真的。我做错了什么?
迭代器 - 同步和异步 - 具有延迟执行 - 基本上,状态机在实际
foreach
之前处于非活动状态。但是,您可以通过稍微重组来轻松解决此问题:
public IAsyncEnumerable<Pport> GetMessages()
{
// note: this is neither "async" nor has "yield"
Console.Error.WriteLine("Start getting messages");
var timestamp = DateTime.MinValue;
return GetMessagesCore(timestamp);
}
private async IAsyncEnumerable<Pport> GetMessagesCore(DateTime timestamp)
{
// some code which start downloading a large file from FTP
... yield etc
}
此方法也经常用于允许 only
private
方法具有 [EnumeratorCancellation] CancellationToken cancellationToken
参数以与 WithCancellation()
一起使用