3

当使用文件流并设置FileShareNone,并表示同时访问同一功能的两个用户想要读取/写入该文件时。会让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 说:无 拒绝共享当前文件。任何打开文件的请求(通过这个进程或另一个进程)都会失败,直到文件被关闭。

但是请求会继续尝试直到文件流关闭吗?

4

2 回答 2

3

当一个进程打开一个文件进行读/写时FileShare.None,任何进程对该文件的任何后续访问都将导致Acess Denied Exception. 要回答您的问题,第二个用户将获得例外。

MSDN : FileShare.None - 拒绝共享当前文件。任何打开文件的请求(通过这个进程或另一个进程)都会失败,直到文件被关闭。


有很多方法可以处理此类并发文件访问问题,以下代码演示了一种解决这种情况的简单方法。

//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);
    }
}
于 2015-06-12T09:42:31.050 回答
3

不,IOException会抛出一个 with HResult = -2147024864andMessage = 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();
        }
    }
}

由于命名的等待句柄会创建一个临界区,因此应用程序的任何两个线程或进程(使用与等待句柄名称相同的名称)都不能同时执行其中的代码。因此,一个线程或进程进入该部分,以没有人可以访问它的方式打开文件(其他应用程序),执行命令并最后离开临界区以允许您的应用程序的其他线程或进程进入临界区。

于 2015-06-12T09:51:20.833 回答