我正在尝试编写一个类,让我可以对多个文件(如 5-10)进行读写操作,同时锁定它们以防止任何类型的访问。每次我访问一个文件(无论是读取还是写入)都会创建一个具有相同名称和不同扩展名的新文件,因此其他线程(属于不同的应用程序)会收到锁定通知(例如 message.msg -> 锁定文件 message.lock 创建)。
应用程序的每个实例都将写入它自己的文件并读取所有其他应用程序文件(包括它的)。
不幸的是,当我启动使用此类的应用程序的多个实例(如 3-4 个)时,即使起初它们看起来正在工作,但在几秒钟/几分钟后,它看起来就像一个线程无法释放文件。这当然也会阻止其他无法读取该特定文件的线程。
我这样说是因为当所有应用程序冻结时,我可以看到一个永久的 .lock 文件。
当然我可以设置一个锁定过期时间(在这种情况下可能会起作用),但是为什么会这样呢?对我来说,这段代码看起来很合理,但我当然还是个新手......所以......我的比例有什么市长缺陷吗?
(不要被它的长度吓到,它们只有 2 个功能,它们做的事情几乎相同,除了中央部分)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace y3kMessenger
{
static class FileLockAccess
{
public static string[] readAllLines(string path)
{
bool isLocked = false;
string[] toReturn;
string lockPath = path.Replace(Global.msgExtension, Global.lockExtension);
StreamWriter w;
//locking ...
while (!isLocked)
{
if (!File.Exists(lockPath))
{
try
{
using (w = new StreamWriter(lockPath))
{
w.WriteLine(" ");
}
isLocked = true;
}
catch (Exception e) { }
}
Thread.Sleep(10);
}
//locked, proceed with read
toReturn = File.ReadAllLines(path);
//release the lock
while (isLocked)
{
try
{
File.Delete(lockPath);
}
catch (Exception e) { }
isLocked = false;
}
return toReturn;
}
public static void writeLine(string path, string text, bool append)
{
bool isLocked = false;
string lockPath = path.Replace(Global.msgExtension, Global.lockExtension);
StreamWriter w;
//locking ...
while (!isLocked)
{
if (!File.Exists(lockPath))
{
try
{
using (w = new StreamWriter(lockPath))
{
w.WriteLine(" ");
}
isLocked = true;
}
catch (Exception e) { }
}
Thread.Sleep(10);
}
//locked, proceed with write
using (w = new StreamWriter(path, append))
w.WriteLine(text);
//release the lock
while (isLocked)
{
try
{
File.Delete(lockPath);
}
catch (Exception e) { }
isLocked = false;
}
}
}
}
编辑:作为讨论的补充,以下代码似乎有效:
public static string[] readAllLines(string path)
{
bool done = false;
string[] toReturn = null;
while (!done)
{
try
{
toReturn = File.ReadAllLines(path);
done = true;
}
catch (Exception e)
{
Thread.Sleep(50);
}
}
return toReturn;
}
public static void writeLine(string path, string text, bool append)
{
bool done = false;
while (!done)
{
try
{
using (StreamWriter w = File.AppendText(path))
{
w.WriteLine(text);
}
done = true;
}
catch (Exception e)
{
Thread.Sleep(50);
}
}
}
所以问题不应该在于线程正在做什么(我没有更改任何其他内容,因为这些方法公开的接口与前两个相同)