vto*_*ola 8 .net c# multithreading synchronization filestream
我的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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我不喜欢这样一个事实:我必须抓住异常,尝试几次并等待不准确的时间:|
您可以通过使用流构造函数的 FileMode.CreateNew 参数来处理此问题。其中一个线程将丢失并发现该文件已由另一个线程提前一微秒创建。并且会得到一个IOException。
然后它需要旋转,等待文件完全创建。您可以通过 FileShare.None 强制执行。这里捕获异常并不重要,无论如何它都会旋转。无论如何,除非您 P/Invoke,否则没有其他解决方法。