6

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

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

我只想在 15 分钟内没有写完的情况下才写完。

我知道有一个 lock 关键字,所以我应该把所有东西都包在一个 lock 中,然后检查它是否在 15 分钟或更长时间内更新,反之亦然?

更新

工作流程:

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

4

7 回答 7

2

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

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

更新:我假设你有一个共享对象。如果这些是同一台机器上的不同进程,则您需要像命名互斥锁这样的东西。看这里的例子

于 2008-09-18T15:30:33.963 回答
1

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

于 2008-09-18T15:35:20.613 回答
1

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

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

现在剩下的就是查找如何使用 msdn 执行上述操作(抱歉,我懒得全部查找,而且我不太记得 C# 类)。:)

于 2008-09-18T15:58:23.540 回答
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
}

这将跨线程进程工作。

于 2008-10-04T16:03:30.723 回答
0

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

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

如果你在不同的机器上,你的里程可能会有所不同——win32声称有文件锁定,可以在网络上工作,但从历史上看,依赖它的应用程序(想想MSAccess)无论如何都会有文件损坏的问题。

于 2008-09-18T15:35:26.497 回答
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);
      }
   }
于 2008-09-18T15:38:32.633 回答
0

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

于 2011-03-25T10:19:25.030 回答