在PowerShell中通过C#编写的Cmdlet获取IAsyncEnumerable方法结果
解决方案
你可以通过手动遍历IAsyncEnumerable的异步枚举器,在同步上下文下逐个等待返回结果即可适配PowerShell的同步执行逻辑,PowerShell线程默认无SynchronizationContext,直接使用GetAwaiter().GetResult()不会出现死锁问题。
实现代码(替换你原有的EndProcessing方法)
protected override void EndProcessing() { // 拿到异步枚举器 var enumerator = InternalMethodAsync().GetAsyncEnumerator(); try { // 循环等待下一个元素,直到枚举结束 while (enumerator.MoveNextAsync().AsTask().GetAwaiter().GetResult()) { var currentValue = enumerator.Current; // 构造你要输出的对象写入PowerShell管道 WriteObject(new FavoriteStuff { FavoriteNumber = currentValue, FavoritePet = FavoritePet }); } } finally { // 释放异步枚举器资源 enumerator.DisposeAsync().AsTask().GetAwaiter().GetResult(); } }
可选简化方案(需要引入NuGet包System.Linq.Async)
如果你不介意引入额外依赖,可以直接调用异步LINQ扩展方法一次性拿到所有结果:
using System.Linq; protected override void EndProcessing() { var allValues = InternalMethodAsync().ToListAsync().GetAwaiter().GetResult(); foreach (var value in allValues) { WriteObject(new FavoriteStuff { FavoriteNumber = value, FavoritePet = FavoritePet }); } }
说明
- 第一种无依赖方案还可以实现流式输出:每生成一个结果就立刻写入PowerShell管道,用户不需要等10秒才能看到所有输出,每秒都会返回一条结果,体验更好
- 第二种方案会等待所有结果生成完成后才统一输出,适合结果量不大的场景
内容的提问来源于stack exchange,提问作者ThanoojJ
相关产品推荐
相关产品推荐

