2008-09-18 30 views
6

在一个asp.net web应用程序中,我想写入一个文件。该功能将首先从数据库中获取数据,然后写出平面文件。想写入一个文件,但一次可能有多个写入者,需要锁定

我该怎么做才能确保只发生1次写入,一旦发生写入,写入之后可能要写入文件的其他线程就不会发生。

我想只在15分钟内完成这个写操作。

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

更新

工作流程:

因为这是一个Web应用程序,多个实例将是人查看特定网页。我可以使用缓存系统中的构建,但是如果asp.net重新使用,重建缓存将会很昂贵,所以我只想将其写入一个平面文件。我的其他选择只是创建一个Windows服务,但这是更多的工作来管理我想要的。

+0

所有的写入是在单个应用程序的单个实例中发生的吗?或者,应用程序的多个实例会试图同时写入,还是会尝试同时写入不同的应用程序? – 2008-09-18 15:34:12

回答

2

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

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

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

+0

我认为这是行不通的,因为我在下面解释过。 – MarkR 2008-09-18 15:36:36

1

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

0

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

假设你所有的进程都在同一台机器上运行,文件锁定应该这样做。如果你在不同的机器上,你的里程可能会有所不同,win32声称有文件锁定在网络上工作,但历史上依赖它的应用程序(Think MSAccess)无论如何都有文件损坏的问题。

+0

你说得对,为了锁的工作,你需要所有的方法来使用“this”的同一个实例。这里的解决方案可能是创建一个** static ** dummy对象实例,它将确保。 – 2012-01-21 18:09:45

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); 
     } 
    } 
+0

这与lock(lockObj){}完全相同。 – 2008-10-04 15:34:34

1

写入文件的文件I/O操作会自动锁定文件。检查文件是否被锁定(通过尝试写入),如果不写入。在做任何写操作之前,检查文件的时间戳,看看它是否超过15分钟。

afaik您不能写入文件,而不会被Windows锁定/不管。

现在,所有剩下的事情就是查找如何使用msdn来完成上述操作(对不起,我不能费心去查看它,并且我不记得C#类很好)。 :)

+1

请注意,我的答案取决于时间戳是可靠的 - 并不总是一个好的假设。您可以在任何过程完成写入之后,将文件保持打开状态,仅写入15分钟。 :) – jheriko 2012-03-19 03:59:35

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 
} 

这将跨线程处理工作。

0

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

相关问题