要写入文件,但可能一次有多个写入者,需要锁定
在asp.net Web应用程序中,我想写入文件。此函数将首先从数据库中获取数据,然后写出平面文件。
我该怎么做才能确保仅发生1次写操作,并且一旦发生写操作,由于发生了写操作,其他可能要写入文件的线程也就不会出现。
我想仅在15分钟内未完成写入操作。
我知道有一个lock关键字,因此我应该将所有内容都包装在一个锁中,然后检查它是否在15分钟或者更长时间内已更新,反之亦然?
更新
工作流程:
由于这是一个Web应用程序,因此多个实例将是查看特定网页的人员。我可以使用内置缓存系统,但是如果asp.net回收,则重建缓存会很昂贵,因此我只想将其写到平面文件中。我的另一个选择是仅创建Windows服务,但这是我想要管理的更多工作。
解决方案
同步编写代码以锁定共享库,以便只有一个线程进入该块内。其他人则等到当前的一个退出。
lock(this) { // perform the write. }
更新:我假设我们有一个共享库。如果这些是同一台计算机上的不同进程,则需要诸如Named Mutex之类的东西。在这里看一个例子
锁定对象变量而不是整个实例不是更好吗?
我不相信.NET的锁定适用于不同的进程。而且,lock(this)将只排除在" this"的同一实例上运行该方法的其他线程,因此,即使在同一进程中,其他线程也可以一次在不同的实例上运行。
假设所有进程都在同一台计算机上运行,那么文件锁定应该可以做到。
如果我们使用的是不同的计算机,则工作量可能会有所不同win32声称具有可在网络上运行的文件锁定功能,但从历史上看,依赖它的应用程序(认为MSAccess)总会出现文件损坏的问题。
// 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); } }
写入文件的文件I / O操作将自动锁定文件。检查文件是否被锁定(尝试写入),以及是否未写入。在进行任何写操作之前,请检查文件上的时间戳,并查看其是否超过15分钟。
afaik,我们无法将文件写入文件,除非文件被Windows锁定。
现在剩下的就是使用msdn查找如何执行上述操作(对不起,我不愿意查找全部内容,并且我不太记得Cclass)。 :)
使用文件系统锁
像其他建议的一样,在这种情况下,.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 }
这将跨线程和进程工作。