Raised exception in the case of concurrent file access with StreamReader

烂漫一生 提交于 2019-12-07 14:04:56

问题


I found a post talking about handling concurrent file access with StreamWriter.

The problem is that the answers do not manage the scenario where the file is being accessed but multiple processes.

Let's tell it shortly :

  • I have multiple applications
  • I need a centralised logging system in dataBase
  • If database fail, I need a fallback on a file system log

There is a known concurrency scenario, where multiple applications (processes) will try to write in that file. This can be managed by re-attempt the writing after a short delay. But I don't want ot reattempt if it's a security error or filename syntax error.

The code is here :

// true if an access error occured
bool accessError = false;
// number fo writing attemps
int attempts = 0;

do
{
    try
    {
        // open the file
        using (StreamWriter file = new StreamWriter(filename, true))
        {
            // write the line
            file.WriteLine(log);
            // success
            result = true;
        }
    }
        /////////////// access errors ///////////////
    catch (ArgumentException)
    {
        accessError = true;
    }
    catch (DirectoryNotFoundException)
    {
        accessError = true;
    }
    catch (PathTooLongException)
    {
        accessError = true;
    }
    catch (SecurityException)
    {
        accessError = true;
    }
        /////////////// concurrent writing errors ///////////////
    catch (Exception)
    {
        // WHAT EXCEPTION SHOULD I CATCH HERE ?
        // sleep before retrying
        Thread.Sleep(ConcurrentWriteDelay);
    }
    finally
    {
        attempts++;
    }
    // while the number of attemps has not been reached
} while ((attempts < ConcurrentWriteAttempts)
            // while we have no access error
            && !accessError
            // while the log is not written
            && !result);

My only question is the type of exception that will be raised in the case of concurrency writting. I already know things can be done differently. Let me add a few considerations :

  • No, I don't want to use NLog in that scenario
  • Yes I handle concurrency with IOC + Mutex for the in-process concurrency
  • Yes I really want all log to be written in the same file

回答1:


It will be an IOException with text:

"The process cannot access the file '{0}' because it is being used by another process."

This is a simplistic approach:

 static bool LogError(string filename, string log)
    {
        const int MAX_RETRY = 10;
        const int DELAY_MS = 1000; // 1 second
        bool result = false;
        int retry = 0;
        bool keepRetry = true;
        while (keepRetry && !result && retry < MAX_RETRY )
        {
            try
            {
                using (StreamWriter file = new StreamWriter(filename, true))
                {
                    // write the line
                    file.WriteLine(log);
                    // success
                    result = true;
                }
            }
            catch (IOException ioException)
            {
                Thread.Sleep(DELAY_MS);
                retry++; 
            }
            catch (Exception e)
            {

                keepRetry = false;
            }

        }
        return result;
    }


来源:https://stackoverflow.com/questions/4324719/raised-exception-in-the-case-of-concurrent-file-access-with-streamreader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!