C# 要写入文件,但可能同时有多个写入程序,需要锁定

C# 要写入文件,但可能同时有多个写入程序,需要锁定,c#,.net,asp.net,locking,C#,.net,Asp.net,Locking,在asp.net web应用程序中,我想写入文件。此函数将首先从数据库中获取数据,然后写出平面文件 我可以做些什么来确保只发生1次写入,并且一旦写入发生,可能要写入文件的其他线程在写入发生后就不会写入 我只想在15分钟内写完这篇文章 我知道有一个lock关键字,所以我应该将所有内容都封装在一个锁中,然后检查它是否在15分钟或更长时间内更新,或者反之亦然 更新 工作流程: 由于这是一个web应用程序,因此多个实例将是查看特定网页的人。我可以使用内置的缓存系统,但如果asp.net进行回收,则重建缓

在asp.net web应用程序中,我想写入文件。此函数将首先从数据库中获取数据,然后写出平面文件

我可以做些什么来确保只发生1次写入,并且一旦写入发生,可能要写入文件的其他线程在写入发生后就不会写入

我只想在15分钟内写完这篇文章

我知道有一个lock关键字,所以我应该将所有内容都封装在一个锁中,然后检查它是否在15分钟或更长时间内更新,或者反之亦然

更新

工作流程:


由于这是一个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分钟内不写入。:)