进程无法访问该文件,因为另一个进程正在使用该文件:读取/写入文件的正确方法:大量使用的应用程序第二部分
本文关键字:文件 进程 方法 应用程序 第二部分 另一个 访问 因为 读取 | 更新日期: 2023-09-27 18:10:37
我们有一个使用频繁的.Net 3.5应用程序,它读取"创建成本高昂"的数据并将其缓存。然而,在读取缓存文件和写入缓存文件时,我们都会遇到很多错误。我从StackOverflow论坛得到的一些建议是:
- a。在"FileShare.read"模式下读取文件,并在中写入文件"FileShare.ReadWrite"模式。("FileAccess"模式应该是什么在系统进行读/写操作时使用。(
- b。在每次读取和写入操作之后使用"GC.Collect"。(什么每次之后这样做对性能有影响吗读''写操作。(
这是正确的读写文件方式吗?请告知。
private XmlDocument ReadFromFile(string siteID, Type StuffType)
{
XmlDocument result = null;
var fsPath = FileSystemPath(siteID, StuffType.Name);
result = new XmlDocument();
using (var streamReader = new StreamReader(fsPath))
//using (var fileStream = new FileStream(fsPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
result.Load(streamReader);
}
//GC.Collect();
return result;
}
private readonly object thisObject = new object();
private void WriteToFile(string siteID, XmlDocument stuff, string fileName)
{
var fsPath = FileSystemPath(siteID, fileName);
lock (thisObject)
{
//using (var fileStream = new FileStream(fsPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var streamWriter = new StreamWriter(fsPath))
{
stuff.Save(streamWriter);
}
//GC.Collect();
}
}
如果您想同步对资源的访问,根据上下文有几个选项。有几种(通用(情况:
-
单进程,单线程
不需要同步。
-
单进程,多线程
使用类似
lock
或ReaderWriterLockSlim
的简单锁定机制。 -
多进程,单机
使用(命名的(
Mutex
。Mutex不是很快。更多关于底部性能的信息。 -
多个进程,多台机器
现在它开始感兴趣了。NET对此没有现成的解决方案。我能想到两种解决方案:
- 重试方法:制作一个while循环,里面有一个try-catch。让他在试用范围内进行资源操作。如果成功,则返回一个成功的结果。如果失败,请等待几毫秒,然后重试。。。再一次。。。再一次
- 同步主机:使Web服务在网络的中心位置运行。所有想要访问资源的进程都必须首先向服务请求权限。如果资源被"锁定",则服务将等待,从而导致进程将等待。一旦资源被释放,就会通知服务,并允许下一个进程访问该资源
在这种情况下
当然,最后一个解决方案是通用解决方案。在Ajit Goel的情况下,它就像创建一个读/写文件的集中式服务一样简单。然后你有一个filemaster,它控制iets文件。
另一种解决方案可能是将所有文件存储在一个中央数据库中,并让他进行所有同步。
性能
如果性能开始成为一个问题,您可以尝试创建一个缓存。
- 您可以在内存中创建一个缓存(但对于大量文件或大文件,这可能会成为内存问题(
- 您可以在本地文件夹中创建一个缓存(每个进程一个(。一旦修改了集中位置(只需验证日期(,您就可以将该文件(带有Mutex锁(复制到自己的本地文件夹中。从那里,你可以通过读取访问和读取共享在没有锁的情况下一遍又一遍地读取文件
我认为ReaderWriterLock与FileShare.ReadWrite相结合就是您的解决方案。(注意,我链接到的文档页面向您推荐了一个更好的版本,名为ReaderWriterLockSlim,它应该至少也一样好。(
你需要在每个线程上使用FileShare.ReadWrite,这样他们就可以根据需要访问它。任何时候线程需要读取时,都将其设为AcquireReaderLock
(读取完成时为ReleaseReaderLock
(。
当你想写的时候,只需要使用UpgradeToWriterLock
,当你写完的时候,使用DowngradeFromWriterLock
。
这应该允许所有线程始终以只读方式访问文件,并允许任何一个线程在必要时获取写入权限。
希望能有所帮助!
我相信每个人都必须以FileShare.ReadWrite模式打开文件。
如果有人在FileShare.Read模式下打开它,而其他人试图对它进行写入,它将失败。我认为它们不兼容,因为一个说"只读共享",但另一个想写。您可能需要对所有这些文件使用FileShare.ReadWrite,或者尽量减少写入量以尽量减少冲突。
http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx
另一种选择是使用FileShare.Read,并在进行修改时复制文件。如果所有修改都有一个入口点,那么它可以使用FileShare.Read来复制文件。修改副本,然后更新指示当前文件路径的某种变量/属性。一旦更新,从文件中读取的所有其他进程都将使用该新位置。这将允许修改发生并完成,然后使所有读者都知道新修改的文件。同样,只有当您能够集中修改时才可行。如果需要,可以通过某种修改请求队列。