使用AmazonS3 SDK在C#中调用Backblaze ListBuckets无结果返回问题
解决C#控制台应用调用Backblaze B2 ListBucketsAsync时程序直接终止的问题
核心问题:异步方法未被正确等待
控制台应用的主线程默认不会等待异步任务完成,如果你在Main方法中直接调用StartsHere()而不等待,程序会在异步操作执行前就直接退出,这就是DisplayBucketList从未执行的根本原因。
解决方案步骤:
- 修改Main方法为异步模式
将控制台的入口方法改成异步版本,确保等待异步任务完成:
static async Task Main(string[] args) { // 替换为你的Backblaze凭据 var b2Client = new BackBlazeS3("你的BucketId", "你的ApplicationKey", "你的KeyId"); await b2Client.StartsHere(); // 防止程序执行完立即退出 Console.WriteLine("\n按任意键退出..."); Console.ReadKey(); }
- 修正Backblaze S3客户端配置
Backblaze B2的S3兼容模式需要特定配置,补充签名版本和路径风格设置,同时建议使用HTTPS:
s3Config = new AmazonS3Config() { ServiceURL = "https://s3.us-east-005.backblazeb2.com", SignatureVersion = "4", // Backblaze要求V4签名 ForcePathStyle = true // Backblaze使用路径风格的存储桶寻址 };
- 完善错误处理,避免空引用崩溃
如果ListBucketsAsync请求失败返回null,后续访问response.Buckets会触发空引用异常,需要增加判空逻辑:
public async Task<bool> StartsHere() { try { _s3Client = new AmazonS3Client(_key_id, _application_key, s3Config); var response = await GetBuckets(_s3Client); if (response != null && response.Buckets != null) { DisplayBucketList(response.Buckets); } else { Console.WriteLine("未获取到存储桶列表,请求可能失败"); } } catch (Exception ex) { Console.WriteLine($"错误信息: {ex.Message}\n堆栈跟踪: {ex.StackTrace}"); } return true; }
- 简化日志文件初始化
原代码中创建日志文件的写法可以简化,避免手动Dispose:
// 替换构造函数中的日志文件代码 Directory.CreateDirectory(logFileFolder); if (!File.Exists(logFilePath)) { File.Create(logFilePath).Close(); }
修改后的完整类代码
public class BackBlazeS3 { public AmazonS3Config s3Config = new AmazonS3Config(); private IAmazonS3 _s3Client; private string logFileFolder = @"C:\temp\bbi"; private string logFilePath = @"C:\temp\bbi\log.txt"; private string _bucketId = ""; private string _application_key = ""; private string _key_id = ""; public BackBlazeS3(string bucketId, string application_key, string key_id) { Console.WriteLine("Log file check"); Directory.CreateDirectory(logFileFolder); if (!File.Exists(logFilePath)) { File.Create(logFilePath).Close(); } _application_key = application_key; _bucketId = bucketId; _key_id = key_id; s3Config = new AmazonS3Config() { ServiceURL = "https://s3.us-east-005.backblazeb2.com", SignatureVersion = "4", ForcePathStyle = true }; } public async Task<bool> StartsHere() { try { _s3Client = new AmazonS3Client(_key_id, _application_key, s3Config); var response = await GetBuckets(_s3Client); if (response != null && response.Buckets != null) { DisplayBucketList(response.Buckets); } else { Console.WriteLine("未获取到存储桶列表,请求可能失败"); } } catch (Exception ex) { Console.WriteLine($"错误信息: {ex.Message}\n堆栈跟踪: {ex.StackTrace}"); } return true; } public async Task<ListBucketsResponse> GetBuckets(IAmazonS3 client) { Console.WriteLine("GetBuckets"); ListBucketsResponse returned = null; try { returned = await client.ListBucketsAsync(); } catch (Exception ex) { Console.WriteLine($"获取存储桶失败: {ex.Message}."); } return returned; } public void DisplayBucketList(List<S3Bucket> bucketList) { Console.WriteLine("DisplayBucketList"); bucketList .ForEach(b => Console.WriteLine($"Bucket name: {b.BucketName}, created on: {b.CreationDate}")); } }
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

