如何移除含await foreach方法中的async与await,转为同步方法?
如何将异步foreach的异步方法改为同步方法?
可以将这个异步方法改为同步实现,但因为ListObjectsEnumAsync返回的是**IAsyncEnumerable<T>**(异步枚举器),不能直接用普通的.Result处理,需要手动遍历异步枚举器的同步版本。
修改后的同步代码示例:
public static void Run(IMinioClient minio, string bucketName = "my-bucket-name", string prefix = null, bool recursive = true, bool versions = false) { try { Console.WriteLine("Running example for API: ListObjectsAsync"); var listArgs = new ListObjectsArgs() .WithBucket(bucketName) .WithPrefix(prefix) .WithRecursive(recursive) .WithVersions(versions); // 获取异步枚举器并同步遍历 var asyncEnumerator = minio.ListObjectsEnumAsync(listArgs).ConfigureAwait(false).GetAsyncEnumerator(); try { while (asyncEnumerator.MoveNextAsync().GetAwaiter().GetResult()) { var item = asyncEnumerator.Current; Console.WriteLine($"Object: {item.Key}"); } } finally { // 确保异步枚举器被正确释放 asyncEnumerator.DisposeAsync().GetAwaiter().GetResult(); } Console.WriteLine($"Listed all objects in bucket {bucketName}\n"); } catch (Exception e) { Console.WriteLine($"[Bucket] Exception: {e}"); } }
关键注意事项:
- 使用
GetAwaiter().GetResult()替代.Result:前者会直接抛出原始异常,和await的异常行为一致,而.Result会将异常包装为AggregateException,增加异常处理复杂度。 - 必须手动释放异步枚举器:
IAsyncEnumerator实现了IAsyncDisposable,需要调用DisposeAsync()并同步等待完成,避免资源泄漏(比如未关闭的网络连接)。 - 警惕死锁风险:在存在
SynchronizationContext的环境(如WinForms、WPF、老版本ASP.NET)中,同步阻塞异步代码可能导致死锁。如果你的应用运行在这类环境中,优先保留异步实现更安全。
内容的提问来源于stack exchange,提问作者François Schuster
相关产品推荐
相关产品推荐

