C# 要写入文件,但可能同时有多个写入程序,需要锁定
在asp.net web应用程序中,我想写入文件。此函数将首先从数据库中获取数据,然后写出平面文件 我可以做些什么来确保只发生1次写入,并且一旦写入发生,可能要写入文件的其他线程在写入发生后就不会写入 我只想在15分钟内写完这篇文章 我知道有一个lock关键字,所以我应该将所有内容都封装在一个锁中,然后检查它是否在15分钟或更长时间内更新,或者反之亦然 更新 工作流程:C# 要写入文件,但可能同时有多个写入程序,需要锁定,c#,.net,asp.net,locking,C#,.net,Asp.net,Locking,在asp.net web应用程序中,我想写入文件。此函数将首先从数据库中获取数据,然后写出平面文件 我可以做些什么来确保只发生1次写入,并且一旦写入发生,可能要写入文件的其他线程在写入发生后就不会写入 我只想在15分钟内写完这篇文章 我知道有一个lock关键字,所以我应该将所有内容都封装在一个锁中,然后检查它是否在15分钟或更长时间内更新,或者反之亦然 更新 工作流程: 由于这是一个web应用程序,因此多个实例将是查看特定网页的人。我可以使用内置的缓存系统,但如果asp.net进行回收,则重建缓
由于这是一个web应用程序,因此多个实例将是查看特定网页的人。我可以使用内置的缓存系统,但如果asp.net进行回收,则重建缓存的成本会很高,因此我只想将其写入一个平面文件。我的另一个选择是只创建一个windows服务,但这是我想要管理的更多工作。同步编写代码以锁定共享对象,以便只有一个线程进入块。其他人则等待当前的退出
lock(this)
{
// perform the write.
}
更新:我假设你有一个共享对象。如果在同一台机器上有不同的进程,则需要类似命名互斥的东西 锁定一个对象变量而不是整个实例不是更好吗?我不相信.NET的锁定适用于不同的进程。此外,lock(this)将只排除在“this”的同一实例上运行该方法的其他线程,因此即使在同一进程中的其他线程也可以在不同实例上同时运行 假设所有进程都在同一台机器上运行,那么文件锁定应该可以做到这一点
如果您在不同的机器上,您的里程可能会有所不同-win32声称具有通过网络工作的文件锁定功能,但从历史上看,依赖它的应用程序(想想MSAccess)无论如何都存在文件损坏问题。写入文件的文件I/O操作将自动锁定文件。检查文件是否已锁定(通过尝试写入)以及文件是否已锁定(不写入)。在进行任何写入之前,请检查文件上的时间戳,并查看其是否超过15分钟
// try enter will return false if another thread owns the lock
if (Monitor.TryEnter(lockObj))
{
try
{
// check last write time here, return if too soon; otherwise, write
}
finally
{
Monitor.Exit(lockobj);
}
}
如果文件没有被Windows/任何东西锁定,则无法写入文件
现在,您只需查找如何使用msdn执行上述操作(对不起,我不想费心全部查找,而且我对C#类的记忆也不太清楚。):) 使用文件系统锁 与其他人建议的一样,.NET锁在这种情况下使用有限。 代码如下:
FileInfo fi = new FileInfo(path);
if (fi.Exists
&& (DateTime.UtcNow - fi.LastWriteTimeUtc < TimeSpan.FromMinutes(15)) {
// file is fresh
return;
}
FileStream fs;
try {
fs = new FileStream(
path, FileMode.Create, FileAccess.Write, FileShare.Read);
} catch (IOException) {
// file is locked
return;
}
using (fs) {
// write to file
}
FileInfo-fi=新的FileInfo(路径);
如果(fi)存在
&&(DateTime.UtcNow-fi.LastWriteTimeUtc
这将贯穿线程和进程。
你应该考虑。它可以在多个线程和进程之间同步。是否所有的写入都发生在单个应用程序的单个实例中?还是应用程序的多个实例同时试图写入,或者不同的应用程序会被ATTEM写入。选择同时写入?我认为这行不通,原因我已经在下面解释过了。这与lock(lockObj){}完全相同。您是对的,为了使锁工作,您将需要所有方法来使用“this”的同一个实例。这里的解决方案可能是创建一个静态虚拟对象实例,这将确保。注意,我的答案取决于时间戳是否可靠-这并不总是一个好的假设。您可以在任何进程完成写入后,让文件保持打开状态,15分钟内不写入。:)