【发布时间】:2023-03-23 13:01:02
【问题描述】:
我的 Web 应用程序从文件系统返回一个文件。这些文件是动态的,所以我无法知道它们的名称或数量。当此文件不存在时,应用程序会从数据库中创建它。我想避免两个不同的线程同时重新创建同一个文件,或者一个线程尝试返回该文件而另一个线程正在创建它。
另外,我不想锁定所有文件通用的元素。因此,我应该在创建文件时锁定它。
所以我想锁定一个文件直到它的重新创建完成,如果其他线程试图访问它......它将不得不等待文件被解锁。
我一直在阅读有关 FileStream.Lock 的信息,但我必须知道文件长度,并且它不会阻止其他线程尝试读取文件,因此它不适用于我的特定情况。
我也一直在阅读有关 FileShare.None 的内容,但是如果其他线程/进程尝试访问该文件,它将引发异常(哪种异常类型?)...所以我应该开发一个“出现故障时再试一次” " 因为我想避免产生异常......而且我不太喜欢这种方法,尽管也许没有更好的方法。
使用 FileShare.None 的方法或多或少是这样的:
static void Main(string[] args)
{
new Thread(new ThreadStart(WriteFile)).Start();
Thread.Sleep(1000);
new Thread(new ThreadStart(ReadFile)).Start();
Console.ReadKey(true);
}
static void WriteFile()
{
using (FileStream fs = new FileStream("lala.txt", FileMode.Create, FileAccess.Write, FileShare.None))
using (StreamWriter sw = new StreamWriter(fs))
{
Thread.Sleep(3000);
sw.WriteLine("trolololoooooooooo lolololo");
}
}
static void ReadFile()
{
Boolean readed = false;
Int32 maxTries = 5;
while (!readed && maxTries > 0)
{
try
{
Console.WriteLine("Reading...");
using (FileStream fs = new FileStream("lala.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
using (StreamReader sr = new StreamReader(fs))
{
while (!sr.EndOfStream)
Console.WriteLine(sr.ReadToEnd());
}
readed = true;
Console.WriteLine("Readed");
}
catch (IOException)
{
Console.WriteLine("Fail: " + maxTries.ToString());
maxTries--;
Thread.Sleep(1000);
}
}
}
但我不喜欢我必须捕获异常,尝试多次并等待不准确的时间:|
【问题讨论】:
-
它是 FileShare.None 而不是 FileAccess.None(FileAccess 定义了您的应用程序具有的访问权限,而 FileShare 用于根据需要锁定文件)
-
关于其他话题,记得在你的应用程序被销毁时解锁文件,我讨厌锁定之后仍然存在。
-
我已经编辑并修复了它,谢谢!
标签: c# .net multithreading synchronization filestream