从单个文件读取的多个请求("由另一个进程使用")

Pau*_*ski 2 c# asp.net iis-7 httphandler .net-2.0

我在这里有一个问题,我希望一些超级专家能够解释.我有一个小的HttpHandler.它从查询字符串中获取文件ID,查找相应的文档路径(来自数据库),并返回响应中的文件内容.

相关代码如下所示:

context.Response.Clear();
context.Response.AddHeader("content-disposition", "attachment;filename=" + file.DisplayName);
context.Response.AddHeader("content-type", mimetype);

string path = context.Server.MapPath(DocumentUploadPath + "/" + file.FileName);

using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[32768];
    int bytesRead = 0;

    while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
    {
        context.Response.OutputStream.Write(buffer, 0, bytesRead);
    }
}
context.Response.OutputStream.Flush();
Run Code Online (Sandbox Code Playgroud)

在今天检查了我们的错误日志之后,我们注意到我们正在获得一些IoExceptions:

该进程无法访问文件'file_path_here',因为它正被另一个进程使用.

为了测试,我设置了一个简单的Parallel.For循环来尝试访问该文件.果然,错误是非常可重复的.它看起来像这样:

static void Main(string[] args)
{
    Parallel.For(0, 1000, ctr =>
    {
        GetFile();
    });
}

static void GetFile()
{
    string fileUrl = "url_to_file.ashx?Id=blah";

    HttpWebRequest request = WebRequest.Create(fileUrl) as HttpWebRequest;

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    string responseText = "";

    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        responseText = reader.ReadToEnd();
    }

    response.Close();
    Console.WriteLine(response.StatusDescription);
}
Run Code Online (Sandbox Code Playgroud)

我修改了处理程序代码以便在遇到该异常时重试,因此问题本身得到了缓解,但这引出了我的一般性问题:

我的服务器如何能够发送数千个index.html的并发副本没问题,但在尝试这个时假设没有中断(假设没有缓存)?服务器是否为我处理重试,或者它是否能以某种方式同时读取index.html?

L.B*_*L.B 5

我想,如果你添加FileShare.Read它将解决你的问题

请参阅解释:http://msdn.microsoft.com/en-us/library/system.io.fileshare(v=vs.110).aspx

此枚举的典型用法是定义两个进程是否可以同时从同一文件读取.例如,如果打开文件并指定了Read,则其他用户可以打开文件进行读取但不能写入.

using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
   .....
}
Run Code Online (Sandbox Code Playgroud)