【问题标题】:Raised exception in the case of concurrent file access with StreamReader在使用 StreamReader 并发文件访问的情况下引发异常
【发布时间】:2011-05-18 12:07:55
【问题描述】:

我找到了post talking about handling concurrent file access with StreamWriter

问题在于答案并不管理正在访问文件的场景,而是多个进程。

让我们简短地告诉它:

  • 我有多个应用程序
  • 我需要数据库中的集中式日志记录系统
  • 如果数据库失败,我需要回退文件系统日志

有一个已知的并发场景,多个应用程序(进程)将尝试写入该文件。 这可以通过在短暂延迟后重新尝试写入来管理。 但如果是安全错误或文件名语法错误,我不想重试。

代码在这里:

// 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);

我唯一的问题是在并发写入的情况下将引发的异常类型。我已经知道事情可以做不同的事情。让我补充一些注意事项:

  • 不,我不想在那种情况下使用 NLog
  • 是的,我使用 IOC + Mutex 处理并发,以实现进程内并发
  • 是的,我真的希望所有日志都写入同一个文件中

【问题讨论】:

    标签: c# concurrency streamwriter


    【解决方案1】:

    它将是一个带有文本的IOException

    “进程无法访问文件‘{0}’,因为它正被另一个进程使用。”

    这是一个简单的方法:

     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;
        }
    

    【讨论】:

    • 感谢您的回答,对您的来源非常感兴趣!
    • 哦,我的意思是信息的来源^^ 但是对于感兴趣的用户来说,sn-p 也很酷(我的有点太长了)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2021-12-26
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多