跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何在C#中异步操作MongoDB GridFS文件驱动_使用GridFSBucketAsync接口

GridFSBucket 无 GridFSBucketAsync 类,所有异步操作均通过 GridFSBucket 的 Async 后缀方法完成;关键方法包括 OpenUploadStreamAsync、OpenDownloadStreamAsync、DeleteAsync、FindAsync 及 CloseAsync,且必须 await,否则引发异常或文件不可见。
GridFSBucket
本身不提供
GridFSBucketAsync
接口 —— 这是个常见误解。MongoDB .NET Driver 中没有独立的异步专用类,所有 I/O 操作都通过
GridFSBucket
上的
Async
后缀方法完成,且全部基于
Task
,天然支持异步。 为什么找不到 GridFSBucketAsync 类 官方驱动(v2.20+)只暴露一个
GridFSBucket
类型,其设计就是异步优先:
OpenUploadStreamAsync
、
OpenDownloadStreamAsync
、
DeleteAsync
等方法全是
Task
-returning 的。所谓“同步接口”在 GridFS 场景下根本不存在(
OpenUploadStream
等无参同步重载已被移除)。强行搜
GridFSBucketAsync
会 404 或匹配到过时社区封装。 必须 await 的关键异步方法有哪些 以下方法不可忽略
await
,否则会阻塞线程或抛出
InvalidOperationException
(尤其在 ASP.NET Core 中):
bucket.OpenUploadStreamAsync(filename, options)
:返回
GridFSUploadStream
,需 await 才能拿到流对象
bucket.OpenDownloadStreamAsync(objectId)
或
.OpenDownloadStreamByNameAsync(filename)
:必须 await,否则
stream
为 null
bucket.DeleteAsync(objectId)
:删除是异步操作,不 await 不会真正执行
bucket.FindAsync(filter)
:查元数据要用它,不是
Find
上传大文件时 stream.CopyToAsync 必须 await 常见错误是写成
stream.CopyToAsync(fileStream).Wait()
,这在 ASP.NET Core 请求上下文中极易引发死锁。正确做法是全程 async/await: go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载
using var uploadStream = await bucket.OpenUploadStreamAsync("report.pdf"); await inputStream.CopyToAsync(uploadStream); // inputStream 是 HttpRequest.Body 等 await uploadStream.CloseAsync(); // 必须调用,否则文件元数据不写入 files 集合
注意:
CloseAsync()
不可省略 —— 它触发
files
文档写入,否则文件“存在但不可见”。 下载时别把 ObjectId 当字符串硬编码
OpenDownloadStreamAsync
要求参数是
ObjectId
类型,不是字符串。直接传
"60a1b2c3d4e5f67890123456"
会编译失败或运行时报
FormatException
: 从 URL 或 JSON 接收 ID 字符串时,先用
ObjectId.Parse(idString)
转换 若字符串可能非法,用
ObjectId.TryParse(idString, out var oid)
做防护 用
OpenDownloadStreamByNameAsync
可绕过 ID 解析,但要求文件名唯一且已知 真正容易被忽略的是:GridFS 默认桶名是
"fs"
,如果你用了自定义桶(如
bucketName: "uploads"
),却没在
GridFSBucket
构造时传入相同名称,
FindAsync
和
OpenDownloadStreamByNameAsync
会查不到任何文件 —— 因为元数据实际存在
uploads.files
,而非
fs.files
。

相关文章