我在这里有一个问题,我希望一些超级专家能够解释。我有一个小的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();
今天检查了我们的错误日志后,我们注意到我们正在按照以下方式获取一些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);
}
我已修改处理程序代码以便在遇到该异常时重试,因此问题本身得到了缓解,但这引出了我的一般性问题:
我的服务器如何能够发送数千个index.html的并发副本没问题,但在尝试此操作时会中断(假设没有缓存)?服务器是否为我处理重试,或者它是否能以某种方式同时读取index.html?
答案 0 :(得分:5)
我认为,如果您添加FileShare.Read
,它将解决您的问题
请参阅解释:http://msdn.microsoft.com/en-us/library/system.io.fileshare(v=vs.110).aspx
此枚举的典型用法是定义两个进程是否可以同时从同一文件读取。例如,如果打开文件并指定了“读取”,则其他用户可以打开文件进行读取,但不能写入。
using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
.....
}
答案 1 :(得分:1)
C#" FileStream"构造函数允许您指定" FileShare.Read":
http://msdn.microsoft.com/en-us/library/system.io.fileshare%28v=VS.90%29.aspx
FileStream fs =
new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
我相信" Open"方法: