FileShare.None 是否让线程等待文件流关闭?
Does FileShare.None make threads wait until the filestream is closed?
当使用文件流时,将 FileShare
设置为 None
,并假设两个用户同时访问同一功能想要 read/write 该文件。 FileShare.None
是让第二个用户请求等待还是第二个用户的请求会抛出异常?
//two users get to this this code at the same time
using (FileStream filestream = new FileStream(chosenFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (StreamReader sr = new StreamReader(filestream))
using (StreamWriter sw = new StreamWriter(filestream))
{
//reading and writing to file
}
Msdn 说:None 拒绝共享当前文件。任何打开文件的请求(通过此进程或其他进程)都将失败,直到文件关闭。
但是请求会一直尝试直到文件流关闭吗?
当一个进程用 FileShare.None
打开一个文件 Read/Write 时,任何进程对该同一文件的任何后续访问都将导致 Acess Denied Exception
。要回答您的问题,第二个用户将获得例外。
MSDN: FileShare.None - Declines sharing of the current file. Any request to open the
file (by this process or another process) will fail until the file is
closed.
有很多方法可以处理此类并发文件访问问题,以下代码演示了一种解决这种情况的简单方法。
//Retry 5 times when file access fails
int retryCounter = 5;
while (!isFileAccessSuccess && retryCounter > 0)
{
try
{
//Put file access logic here
//If the file has been accessed successfully set the flag to true
isFileAccessSuccess = true;
}
catch (Exception exception)
{
//Log exception
}
finally
{
//Decrease the retry count
--retryCounter;
}
if (!isFileAccessSuccess)
{
//Wait sometime until initiating next try
Thread.Sleep(10000);
}
}
不,IOException
将被抛出 HResult = -2147024864
和 Message = The process cannot access the file 'path' because it is being used by another process.
如果您想同步对文件的访问,您可以使用命名等待句柄。
public class FileAcessSynchronizer
{
private readonly string _path;
private readonly EventWaitHandle _waitHandle;
public FileAcessSynch(string path)
{
_path = path;
_waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "NameOfTheWaitHandle");
}
public void DoSomething()
{
try
{
_waitHandle.WaitOne();
using (FileStream filestream = new FileStream(chosenFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (StreamReader sr = new StreamReader(filestream))
using (StreamWriter sw = new StreamWriter(filestream))
{
//reading and writing to file
}
}
finally
{
_waitHandle.Set();
}
}
}
因为命名等待句柄创建了一个 critical section 应用程序的任何两个线程或进程(使用与等待句柄名称相同的名称)都不能同时执行其中的代码。因此,一个线程或进程进入该部分,以任何人(其他应用程序)都无法访问它的方式打开文件,执行命令,最后离开临界区以允许应用程序的其他线程或进程进入临界区。
当使用文件流时,将 FileShare
设置为 None
,并假设两个用户同时访问同一功能想要 read/write 该文件。 FileShare.None
是让第二个用户请求等待还是第二个用户的请求会抛出异常?
//two users get to this this code at the same time
using (FileStream filestream = new FileStream(chosenFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (StreamReader sr = new StreamReader(filestream))
using (StreamWriter sw = new StreamWriter(filestream))
{
//reading and writing to file
}
Msdn 说:None 拒绝共享当前文件。任何打开文件的请求(通过此进程或其他进程)都将失败,直到文件关闭。
但是请求会一直尝试直到文件流关闭吗?
当一个进程用 FileShare.None
打开一个文件 Read/Write 时,任何进程对该同一文件的任何后续访问都将导致 Acess Denied Exception
。要回答您的问题,第二个用户将获得例外。
MSDN: FileShare.None - Declines sharing of the current file. Any request to open the file (by this process or another process) will fail until the file is closed.
有很多方法可以处理此类并发文件访问问题,以下代码演示了一种解决这种情况的简单方法。
//Retry 5 times when file access fails
int retryCounter = 5;
while (!isFileAccessSuccess && retryCounter > 0)
{
try
{
//Put file access logic here
//If the file has been accessed successfully set the flag to true
isFileAccessSuccess = true;
}
catch (Exception exception)
{
//Log exception
}
finally
{
//Decrease the retry count
--retryCounter;
}
if (!isFileAccessSuccess)
{
//Wait sometime until initiating next try
Thread.Sleep(10000);
}
}
不,IOException
将被抛出 HResult = -2147024864
和 Message = The process cannot access the file 'path' because it is being used by another process.
如果您想同步对文件的访问,您可以使用命名等待句柄。
public class FileAcessSynchronizer
{
private readonly string _path;
private readonly EventWaitHandle _waitHandle;
public FileAcessSynch(string path)
{
_path = path;
_waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "NameOfTheWaitHandle");
}
public void DoSomething()
{
try
{
_waitHandle.WaitOne();
using (FileStream filestream = new FileStream(chosenFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (StreamReader sr = new StreamReader(filestream))
using (StreamWriter sw = new StreamWriter(filestream))
{
//reading and writing to file
}
}
finally
{
_waitHandle.Set();
}
}
}
因为命名等待句柄创建了一个 critical section 应用程序的任何两个线程或进程(使用与等待句柄名称相同的名称)都不能同时执行其中的代码。因此,一个线程或进程进入该部分,以任何人(其他应用程序)都无法访问它的方式打开文件,执行命令,最后离开临界区以允许应用程序的其他线程或进程进入临界区。