在 ASP.NET MVC 中将 FileShare.ReadWrite 与 HttpPostedFile 结合使用
Use FileShare.ReadWrite with HttpPostedFile in ASP.NET MVC
我正在使用下面的代码将已发布的文件保存到服务器,但是该文件正在不断读取并且需要使用 FileShare.ReadWrite 所以我没有收到锁定错误。
httpRequest.Files[0].SaveAs(filePath);
下面是我的阅读方法,如何用HttpPosted文件实现才是正确的方法,性能最好。
using (var fileStream = new FileStream(
fileLocation,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using (var streamReader = new StreamReader(fileStream))
{
xDocument = XDocument.Parse(streamReader.ReadToEnd());
}
}
这是我最好的选择吗?
using (var memoryStream = new MemoryStream())
{
httpRequest.Files[0].InputStream.CopyTo(memoryStream);
var bytes = memoryStream.ToArray();
using (var fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
fs.Write(bytes, 0, bytes.Length);
}
}
问题:
- 你想要一把"Write:Once, Read:Many"锁
假设:
- 文件很小(平均写入操作为 5000 毫秒)
- 没有其他写入或读取操作(只有一个程序具有 2 个功能)
- 您读取文件的次数比写入文件的次数多得多
解决方案
using System;
using System.IO;
using System.Threading;
using System.Web.Mvc;
namespace Whosebug_56307594.Controllers
{
public class HomeController : Controller
{
public ActionResult A()
{
readFile();
return View();
}
public ActionResult B()
{
writeFile();
return View();
}
private static object writeLock = new Object();
private void readFile()
{
while (!Monitor.TryEnter(writeLock, 5000)) ; //wait 5000 ms for the writeLock (serializing access)
using (var stream = new FileStream("filePath", FileMode.Open, FileAccess.Read, FileShare.Read))
using (var reader = new StreamReader(stream))
{
// active read
// xDocument = XDocument.Parse(streamReader.ReadToEnd());
}
}
private void writeFile()
{
lock (writeLock)
{
FileStream stream = null;
while (stream == null) //wait for the active read
{
try
{
stream = new FileStream("filePath", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
// will fail if active read becase FileShare.None while (stream == null) will wait
}
}
Request.Files[0].InputStream.CopyTo(stream);
}// unlock
}
}
}
注:
- 我没有测试负载或只是在网络服务器上测试解决方案
- 我只在纸上测试过
参考:
locking - How long will a C# lock wait, and what if the code crashes during the lock? - Stack Overflow
c# - Deleting files in use - Stack Overflow
multithreading - Is there a way to detect if an object is locked? - Stack Overflow
Implementing Singleton in C# | Microsoft Docs
c# - Using the same lock for multiple methods - Stack Overflow
c# - Write-Once, Read-Many Lock - Stack Overflow
我正在使用下面的代码将已发布的文件保存到服务器,但是该文件正在不断读取并且需要使用 FileShare.ReadWrite 所以我没有收到锁定错误。
httpRequest.Files[0].SaveAs(filePath);
下面是我的阅读方法,如何用HttpPosted文件实现才是正确的方法,性能最好。
using (var fileStream = new FileStream(
fileLocation,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using (var streamReader = new StreamReader(fileStream))
{
xDocument = XDocument.Parse(streamReader.ReadToEnd());
}
}
这是我最好的选择吗?
using (var memoryStream = new MemoryStream())
{
httpRequest.Files[0].InputStream.CopyTo(memoryStream);
var bytes = memoryStream.ToArray();
using (var fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
fs.Write(bytes, 0, bytes.Length);
}
}
问题:
- 你想要一把"Write:Once, Read:Many"锁
假设:
- 文件很小(平均写入操作为 5000 毫秒)
- 没有其他写入或读取操作(只有一个程序具有 2 个功能)
- 您读取文件的次数比写入文件的次数多得多
解决方案
using System;
using System.IO;
using System.Threading;
using System.Web.Mvc;
namespace Whosebug_56307594.Controllers
{
public class HomeController : Controller
{
public ActionResult A()
{
readFile();
return View();
}
public ActionResult B()
{
writeFile();
return View();
}
private static object writeLock = new Object();
private void readFile()
{
while (!Monitor.TryEnter(writeLock, 5000)) ; //wait 5000 ms for the writeLock (serializing access)
using (var stream = new FileStream("filePath", FileMode.Open, FileAccess.Read, FileShare.Read))
using (var reader = new StreamReader(stream))
{
// active read
// xDocument = XDocument.Parse(streamReader.ReadToEnd());
}
}
private void writeFile()
{
lock (writeLock)
{
FileStream stream = null;
while (stream == null) //wait for the active read
{
try
{
stream = new FileStream("filePath", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
// will fail if active read becase FileShare.None while (stream == null) will wait
}
}
Request.Files[0].InputStream.CopyTo(stream);
}// unlock
}
}
}
注:
- 我没有测试负载或只是在网络服务器上测试解决方案
- 我只在纸上测试过
参考:
locking - How long will a C# lock wait, and what if the code crashes during the lock? - Stack Overflow
c# - Deleting files in use - Stack Overflow
multithreading - Is there a way to detect if an object is locked? - Stack Overflow
Implementing Singleton in C# | Microsoft Docs
c# - Using the same lock for multiple methods - Stack Overflow
c# - Write-Once, Read-Many Lock - Stack Overflow