要写入文件,但可能一次有多个写入者,需要锁定

时间:2020-03-06 14:21:54  来源:igfitidea点击:

在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
}

这将跨线程和进程工作。