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

时间:2008-09-18 15:28:21

标签: c# .net asp.net locking

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

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

我希望只有在15分钟内没有完成这个写作。

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

更新

工作流:

由于这是一个Web应用程序,因此多个实例将是查看特定网页的人。我可以使用内置缓存系统,但如果asp.net回收,重建缓存将是昂贵的,所以我只想把它写出来一个平面文件。我的另一个选择只是创建一个Windows服务,但这是管理我想要的更多工作。

7 个答案:

答案 0 :(得分:2)

同步您的编写代码以锁定共享对象,以便只有一个线程进入块内。其他人等到当前的一个退出。

lock(this)
{
  // perform the write.
}

更新:我假设你有一个共享对象。如果这些是同一台机器上的不同进程,则需要类似命名互斥锁的东西。 Looky here for an example

答案 1 :(得分:1)

锁定对象变量而不是整个实例是不是更好?

答案 2 :(得分:1)

写入文件的文件I / O操作将自动锁定文件。检查文件是否被锁定(通过尝试写入)以及是否不写入。在进行任何写入操作之前,请检查文件上的时间戳,看它是否超过15分钟。

afaik如果没有被Windows /其他任何东西锁定,你就无法写入文件。

现在剩下的就是查找如何使用msdn进行上述操作(对不起,我不能费心去查看它,我不记得C#类非常好)。 :)

答案 3 :(得分:0)

我不相信.NET的锁定适用于不同的进程。此外,lock(this)将只排除在“this”的同一个实例上运行该方法的其他线程 - 因此即使在同一进程中的其他线程也可以在不同的实例上同时运行。

假设所有进程都在同一台机器上运行,文件锁定应该这样做。

如果你在不同的机器上,你的里程可能会有所不同 - 声称有文件锁定在网络上运行,但历史上依赖它的应用程序(Think MSAccess)无论如何都有文件损坏问题。

答案 4 :(得分:0)

   // 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);
      }
   }

答案 5 :(得分:0)

使用文件系统锁

与其他人一样,.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
}

这将适用于线程进程。

答案 6 :(得分:0)

你们应该考虑一个Mutex。它可以在多个线程和进程之间同步。