等待资源可用
本文关键字:资源 等待 | 更新日期: 2023-09-27 18:08:31
当我得到:
时,是否有一个好方法来执行此代码(等待直到该文件解锁):进程不能访问该文件,因为它正在被另一个进程使用
我在一个web应用程序上工作,所以我可以从几个不同的应用程序并发访问这个文件。
bool isLock = false;
do
{
try
{
File.WriteAllText(path, value, Encoding.Unicode);
isLock = false;
}
catch
{
Thread.Sleep(30);
isLock = true;
}
}while (isLock);
当场景中有多个应用程序时,lock变量是没有用的。
不如测试一下你是否可以File。OpenWrite,然后写入文件。如果无法访问文件循环并等待或写入临时文件,则启动另一个线程循环并等待,直到临时文件可以合并。
也许更好的方法是立即存储到temp,并让看门狗写入您的存储文件。
public void SomeWhereInYourWebServerApplication
{
FileSystemWatcher fsw = new FileSystemWatcher("tempfolder");
fsw.Created += fsw_Created;
// save new entries to tempfolder
}
void fsw_Created(object sender, FileSystemEventArgs e)
{
foreach (string file in Directory.GetFiles("tempfolder"))
{
try
{
string fileText = File.ReadAllText(file);
File.AppendAllText("myStorage.txt", fileText);
File.Delete(file);
}
catch
{
// for me it's ok when we try to append the file the next time
// something new is coming
}
}
}
很好很简单。
当涉及到文件时,不要忘记做适当的异常处理。
如果你绝对必须这样做,并且你无法控制使用该文件的应用程序,那么你的代码就差不多了。
它只需要稍微健壮一点:
public static bool TryWriteText(string path, string text, TimeSpan timeout)
{
Contract.Requires(path != null); // Or replace with: if (path == null) throw new ArgumentNullException("path");
Contract.Requires(text != null); // Or replace with: if (text == null) throw new ArgumentNullException("text");
Stopwatch stopwatch = Stopwatch.StartNew();
while (stopwatch.Elapsed < timeout)
{
try
{
File.WriteAllText(path, text);
return true;
}
catch (IOException){} // Ignore IOExceptions until we time out, then return false.
Thread.Sleep(100); // 100ms is rather short - it could easily be 1000 I think.
} // Perhaps this should be passed in as a parameter.
return false;
}
在超时时重新抛出最后一个IOException
的替代版本(这可能更好,因为您没有隐藏所有异常):
public static void TryWriteText(string path, string text, TimeSpan timeout)
{
Contract.Requires(path != null); // Or replace with: if (path == null) throw new ArgumentNullException("path");
Contract.Requires(text != null); // Or replace with: if (text == null) throw new ArgumentNullException("text");
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
try
{
File.WriteAllText(path, text);
}
catch (IOException)
{
if (stopwatch.Elapsed > timeout)
throw;
}
Thread.Sleep(100);
}
}