使用StreamReader进行并发文件访问时引发exception

我发现了一篇关于使用StreamWriter处理并发文件访问的post 。

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

我们稍后告诉它:

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

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

代码在这里:

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

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

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

它将是一个带有文本的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; }