我有以下代码:
var things = await GetDataFromApi(cancellationToken);
var builder = new StringBuilder(JsonSerializer.Serialize(things));
await things
.GroupBy(x => x.Category)
.ToAsyncEnumerable()
.SelectManyAwaitWithCancellation(async (category, ct) =>
{
var thingsWithColors = await _colorsApiClient.GetColorsFor(category.Select(thing => thing.Name).ToList(), ct);
return category
.Select(thing => ChooseBestColor(thingsWithColors))
.ToAsyncEnumerable();
})
.ForEachAsync(thingAndColor =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId); // prints different IDs
builder.Replace(thingAndColor.Thing, $"{thingAndColor.Color} {thingAndColor.Thing}");
}, cancellationToken);
它用的是System.Linq.Async
,我觉得很难理解.
在"classic "/同步LINQ中,只有当我对其调用ToList()
或ToArray()
时,整个代码才会执行.在上面的例子中,没有这样的调用,但是lambda无论如何都会被执行.它怎麽工作?
我关注的另一个问题是多线程.我听过很多次,异步!=多线程.那么,Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
怎么可能打印不同的身份证呢?一些ID被多次打印,但输出中总共大约有5个线程ID.我的代码中没有一个显式创建任何线程.这一切都是在等待.
StringBuilder
不支持多线程,我想了解一下上面的实现是否有效.
请忽略我的代码的算法,这并不重要,这只是一个例子.重要的是System.Async.Linq的使用.