- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我需要对同一文件进行一批写入,但在文件内的不同位置。我想以尽可能最好的性能实现这一目标,因此查看了同步 FileStream.Write 和异步 FileStream.BeginWrite 方法。
同步实现很简单,只需在循环中调用 FileStream.Write 所需的次数。异步版本在循环中调用 FileStream.BeginWrite,然后执行 WaitHandle.WaitAll 以阻塞直到它们全部完成。令我惊讶的是,这比简单的同步版本慢。
我使用正确的构造函数创建了 FileStream,因此我可以请求异步操作,我还测试了 IAsyncResult.CompletedSynchronous 属性,该属性指示 False,因此它们确实以异步方式运行。似乎使用 BeginWrite 的唯一好处是您不会在写入发生时阻塞您的线程。除了这个好处之外,使用异步版本还有什么意义吗?
这是我用来玩异步方法的测试代码,也许有一个明显的错误?
// Size of a chunk to be written to file
var chunk = 1024 * 64;
// Number of chunks to write async
var reps = 32;
// Create new file and set length
var fs = new FileStream(@"C:\testfile.dat",
FileMode.Create, FileAccess.ReadWrite,
FileShare.None, chunk, true);
fs.SetLength(chunk * reps);
// Allocate resources
byte[] bytes = new byte[chunk];
WaitHandle[] handles = new WaitHandle[reps];
for (int i = 0; i < reps; i++)
{
fs.Seek(chunk * i, SeekOrigin.Begin);
handles[i] = fs.BeginWrite(bytes, 0, chunk, null, null).AsyncWaitHandle;
}
// Wait for all async operations to complete
WaitHandle.WaitAll(handles);
fs.Flush();
fs.Close();
最佳答案
文件写入在 Windows 中得到了高度优化。您实际上并没有写入磁盘,而是写入了文件系统缓存。内存到内存的复制,以每秒 5 GB 或更高的速度运行。然后数据从缓存中延迟写入磁盘。进而优化以最小化写入磁头移动的次数。
这几乎不可能通过异步写入进行优化。这确实需要更长的时间,捕获线程池线程来进行回调并不是免费的。 async 的好处是最小化主线程延迟,而不是真正提高效率。只有当您写入大量数据时,您才会真正受益。超过将适合缓存。到那时,写入性能将从 5 GB/秒急剧下降到低于 ~50 MB/秒,因为缓存空间只能以磁盘写入的速率可用。
很难预测这种情况发生的确切时间。这取决于机器有多少 RAM 以及其他进程需要多少 RAM。当您写入 1 GB 或更少时,您基本上不用担心它。重要的是,当异步写入挂起时,您实际上有一些有用的事情要做。等待他们完成会失去使用它的意义。
关于c# - FileStream.BeginWrite 优于 FileStream.Write?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7733619/
我很好奇在 BeginWrite 实际完成写入之前更改 byte[] 是否会影响 FileStream 最终写入的内容。 下面是这段代码,其中 currentPage 是一个字节[],其中包含我要写入
我正在我的 Unity3D 游戏中实现一个 TCP 客户端,我想知道在不等待上一个调用完成写入的情况下调用 NetworkStream.BeginWrite 是否真的安全。 根据我在阅读文档时的理解,
我有一个文件要填满,所以我想最好同时完成。 注意事项: 我同时从多台计算机获取文件。 我每次都在调用 StartWrite 之前设置位置。 -> 我是否必须在每次使用前锁定它? 它好用吗?你有更好的吗
我的 Sender 类有两个方法: public void SendMessage(OutgoingMessage msg) { try { stream.BeginW
假设我有一个流链,执行压缩 -> 加密 -> 文件 I/O。 在 C# 中,使用同步 I/O,它看起来像这样: int n=0; byte[] buffer= new byte[2048];
我有一个用 C# 编写的实用程序,用于与我们的 USB 设备来回通信。我们使用通用 HID 驱动程序并将设备句柄包装在 FileStream 对象中。我使用它的 BeginRead 和 BeginWr
我需要对同一文件进行一批写入,但在文件内的不同位置。我想以尽可能最好的性能实现这一目标,因此查看了同步 FileStream.Write 和异步 FileStream.BeginWrite 方法。 同
在Realm中有两种写事务的方式,它们有什么区别? 1. try! realm.write { ... } 2. realm.beginWrite() ... try! realm.commitW
异步向客户端写入数据时如何防止这个问题 The BeginWrite method cannot be called when another write operation is pending 我
我是一名优秀的程序员,十分优秀!