我有一个txt文件ABC.txt,它将由多个进程读取和写入。因此,当一个进程正在读取或写入文件ABC.txt时,必须锁定文件ABC.txt,以便任何其他进程无法读取或写入它。我知道枚举System.IO.FileShare可能是处理这个问题的正确方法。但我用另一种方式,我不确定它是否正确。以下是我的解决方案。
我在文件夹中添加了另一个文件Lock.txt。在我可以读取或写入文件ABC.txt之前,我必须能够从文件Lock.txt中读取。在我读取或写入文件ABC.txt后,我必须释放该功能。以下是代码。
#region Enter the lock
FileStream lockFileStream = null;
bool lockEntered = false;
while (lockEntered == false)
{
try
{
lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None);
lockEntered = true;
}
catch (Exception)
{
Thread.Sleep(500);
}
}
#endregion
#region Do the work
// Read from or write to File ABC.txt
// Read from or write to other files
#endregion
#region Release the lock
try
{
if (lockFileStream != null)
{
lockFileStream.Dispose();
}
}
catch
{
}
#endregion
在我的电脑上,似乎此解决方案效果很好,但我仍然无法确定它是否合适。
编辑:多个进程,而不是同一进程中的多线程。
答案 0 :(得分:41)
C#的名字EventWaitHandle是这里的方式。在每个想要使用该文件的进程中创建一个等待句柄实例,并为其指定一个由所有此类进程共享的名称。
EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");
然后在waitHandle
上访问文件等待并完成处理文件后,设置它以便队列中的下一个进程可以访问它。
waitHandle.WaitOne();
/* process file*/
waitHandle.Set();
当您命名事件等待句柄时,该名称将在操作系统中的所有进程之间共享。因此,为了避免冲突的可能性,请使用guid作为名称(上面的“SHARED_BY_ALL_PROCESSES”)。
答案 1 :(得分:8)
C#中的互斥锁可以在多个进程之间共享。以下是写入单个文件的多个进程的示例:
using (var mutex = new Mutex(false, "Strand www.jakemdrew.com"))
{
mutex.WaitOne();
File.AppendAllText(outputFilePath,theFileText);
mutex.ReleaseMutex();
}
您需要确保互斥锁具有唯一的名称,该名称将在整个系统中共享。
补充阅读:
答案 2 :(得分:3)
您的解决方案容易出错。您基本上实现了双重检查锁定(http://en.wikipedia.org/wiki/Double-checked_locking),这可能非常不安全。
更好的解决方案是引入线程隔离,从而只有一个线程访问该文件,并通过从其他线程放置读取或写入请求的队列读取(当然队列受到保护)通过线程的互斥访问)或线程通过同步设备(lock
部分,mutices,等等)或通过使用一些其他文件访问逻辑(例如,System.IO.FileShare
来自同步自己的位置)这里很少有人回应。)
答案 3 :(得分:0)
C#有一个内置的lock
,您可以通过创建一个所有线程都可以访问的静态对象来使用它:
private static object lockObject {get;set;}
public static object LockObject {get{return lockObject ?? lockObject = new object();}}
void YourMethod()
{
lock(LockObject) // all other threads will wait for y
{
using(var lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None))
{
//Do what you need with the file.
}
}
}
这会为您的问题创建线程安全方法。
答案 4 :(得分:0)
如果是我,我会安装类似SQL Server Compact Edition的东西来读/写这些数据。
但是,如果您希望能够锁定对多个进程之间共享的资源的访问,则需要使用Mutex或Semaphore。
Mutex类是围绕OS级锁定机制的.Net包装器。