gpt4 book ai didi

.net - 是否使用由 MemoryMappedFile.OpenExisting 方法线程安全打开的 MemoryMappedFile 实例?

转载 作者:行者123 更新时间:2023-12-01 02:23:44 25 4
gpt4 key购买 nike

在我的 WCF 服务中,我需要提供支持 Range 的文件下载功能用于分 block 下载的 HTTP header 。第一次调用GetFile服务方法创建新的MemoryMappedFile来自磁盘上的文件的实例。假设当第一个请求创建 MMF 并且该请求仍在处理时,第二次调用 GetFile服务打开现有 MMF 并向客户端返回流式响应的方法。如果 MMF 将由创建它的线程处理(并在 MemoryMappedFile 处理上关闭源文件)会发生什么?第二次调用是否应该成功地从已打开的 ViewStream 中读取所有内容?

我写了一个小测试,似乎直到 MemoryMappedFile 由 OpenExisting 打开方法,它的生命周期延长并且源文件保持打开状态。这是真的,还是我错过了一些陷阱?我在 MSDN 中找不到此类案例的任何文档。

更新 :在获取文件的 MapView 之前打开现有 MMF 后添加额外的 Thread.Sleep 调用以模拟线程竞争

private static readonly string mapName = "foo";
private static readonly string fileName = @"some big file";

static void Main(string[] args)
{
var t1 = Task.Factory.StartNew(OpenMemoryMappedFile);
var t2 = Task.Factory.StartNew(ReadMemoryMappedFile);

Task.WaitAll(t1, t2);
}

private static void OpenMemoryMappedFile()
{
var stream = File.OpenRead(fileName);
using (var mmf = MemoryMappedFile.CreateFromFile(stream, mapName, 0, MemoryMappedFileAccess.Read, null, HandleInheritability.None, false))
{
Console.WriteLine("Memory mapped file created");
Thread.Sleep(1000); // timeout for another thread to open existing MMF
}

Console.WriteLine("Memory mapped file disposed");
}

private static void ReadMemoryMappedFile()
{
Thread.Sleep(100); //wait till MMF created
var buffer = new byte[1024 * 1024]; //1MB chunk
long totalLength = 0;
using (var f = File.OpenRead(fileName))
{
totalLength = f.Length;
}

using (var mmf = MemoryMappedFile.OpenExisting(mapName, MemoryMappedFileRights.Read))
{
Console.WriteLine("Existing MMF opened successfully");
Thread.Sleep(2000); //simulate threads race

using (var viewStream = mmf.CreateViewStream(0, 0, MemoryMappedFileAccess.Read))
{

Console.WriteLine("View of file mapped successfully");
File.Delete(Path.GetFileName(fileName));


using (var fileStream = File.Open(Path.GetFileName(fileName), FileMode.CreateNew, FileAccess.Write))
using (var writer = new BinaryWriter(fileStream))
{
int readBytes;
do
{
readBytes = viewStream.Read(buffer, 0, buffer.Length);
writer.Write(buffer, 0, readBytes);

Console.Write("{0:P}% of target file saved\r", fileStream.Length / (float)totalLength);
Thread.Sleep(10); //simulate network latency

} while (readBytes > 0);
Console.WriteLine();
Console.WriteLine("File saved successfully");
}
}
}
}

最佳答案

如果处理了其他文件句柄或什至删除了文件,则不会在您阅读时将打开的 View 拉走。该 View 一直有效,直到您明确关闭它。文件句柄也是如此(您可以在句柄仍然打开和工作时删除文件 - 这是一个鲜为人知的事实)。

假设如果关闭了不同的文件句柄,则它已关闭。然后,您读取它的代码会在执行过程中突然开始在随机点产生访问冲突。那将是一个非常不合理的设计。

顺便说一句,你的线程是基于时间的,因此被破坏了。但我认为你只是想创建一个可以执行的复制案例。

关于.net - 是否使用由 MemoryMappedFile.OpenExisting 方法线程安全打开的 MemoryMappedFile 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18324045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com