我有一个应用程序,它使用XML文件来存储不需要在数据库中的某些数据。这个文件虽然很少,但可能会同时写入页面之间。这会产生一个问题,最有可能导致其中一个页面崩溃。我想知道是否有办法让页面渲染等待,直到另一个完成写入文件。
我不确定我是否可以假设每个页面渲染都在自己的线程中运行;如果是,那么我可以像lock()命令一样暂停该线程以等待资源可用。如果是这样,我如何在文件上实现lock()(因为它不是内存段)?
如果它没有线程或我不能使用lock(),还有哪些方法可以确保写入文件,但如果其他人正在使用该文件,它可以等待文件可用吗? / p>
管理订单和权利的方法很多,但为此很简单;如果你排在第二位,你会在另一个人完成后写下来。我此刻并不关心写冲突,但是并发写作是需要解决的问题。
非常感谢任何帮助!
答案 0 :(得分:2)
编辑:运行更多测试(单声道),我不太确定这是最好的方法。
我没有设法崩溃任何东西,但执行只是在Run()
之后暂停几秒钟,然后回到呼叫者。所以我怀疑这不是支持这段代码的好兆头。
话虽如此,经过测试的情景远非现实。
另一种选择是以FileShare.ReadWrite
模式打开文件,让操作系统关心锁定。
public void Run()
{
var file = @"/home/me/test.txt";
var threads = new Thread[3];
for (int i = 0; i < threads.Length; i++) {
int j = i;
threads[j] = new Thread( s => {
Console.WriteLine("thread " + j + " is running...");
using (var stream = File.Open(file, FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.ReadWrite))
{
Console.WriteLine("thread " + j + " is holding the file!");
var data = ASCIIEncoding.ASCII.GetBytes("hello, I'm stream " + j);
stream.Write(data, 0, data.Length);
Thread.Sleep(1000);
}});
}
foreach (var t in threads)
t.Start();
foreach (var t in threads)
t.Join();
Console.WriteLine(File.ReadAllText(file));
}
输出:
thread 1 is running...
thread 0 is running...
thread 2 is running...
thread 2 is holding the file!
thread 1 is holding the file!
thread 0 is holding the file!
hello, I'm stream 0
答案 1 :(得分:1)
如果它来自一台机器,您可以使用Semaphore
http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx:
private static Semaphore _fileSemaphore = new Semaphore(1, 1, "myFileGlobalSemaphore");
// later...
try
{
_fileSemaphore.WaitOne();
// do stuff..
}
finally
{
_fileSemaphore.Release();
}
这有点像系统范围的锁定。但不是很好,会建议一个DB。另外,其他事情可能会导致文件访问失败。您可以使用适当的锁定模式实现创建FileStream
的内容,如果您尝试打开以供两个来源写入,则会失败,但它不会执行类似lock
的方案(使用内部Monitor
类
顺便说一句:“不需要存储在数据库中”。你问这个问题的事实表明它应该是。如果实施起来很麻烦,您可能需要重新考虑数据访问策略。像Code First的Entity Framework这样的东西可以很容易地“清除”数据库中的内容。
答案 2 :(得分:-2)
使用一些全局锁定对象。例如,添加到global.asax.cs:
public static readonly object FileLock = new Object();
然后在您的页面中使用:
lock(YourApplicationClass.FileLock)
{
// do stuff
}