【问题标题】:C# -- Safe Multiple Thread Save File AccessC# -- 安全多线程保存文件访问
【发布时间】:2015-02-13 16:25:06
【问题描述】:

我目前正在开发一个 C# 应用程序,它使用 两个单独的线程,第一个是程序运行的 主线程,另一个是第二个是日志线程。日志线程基本上是一个大约每秒运行一次的循环,只有在应用程序关闭时才会中断。

基本上,如果有消息要输出,日志线程每隔一秒左右就会写入一个日志文件(文本文件)。我的问题是,在主线程上,我有一个移动功能,可以更改日志文件(和其他文件)的路径,并将旧文件移动到新位置。我的问题是,如果日志线程正在写入日志文件并且移动函数试图移动文件,反之亦然,会发生什么?我将如何帮助防止这种情况发生?

如果我不更改保存路径,程序运行良好,但我担心如果主线程和日志线程同时尝试对日志文件执行某些操作,它们可能会死锁。我已经对此进行了一些研究,但我能想出的只是阻止多个线程同时读取/写入文件的方法,而不是像我一样移动文件并写入文件。那么真的,有什么方法可以让日志线程告诉主线程它正在使用日志文件,而主线程可以在完成后使用日志文件,反之亦然?

多线程是我一直想尝试的东西,但总是被这种事情的复杂性推迟。这当然需要更多的逻辑来阻止事情出错。

非常感谢您的帮助,因为这是应用程序为了防止出现大量错误而需要做的最后一件事(至少我可以说,这就是测试的真正用途)。

编辑: 我真正想要的是两个线程在访问日志文件时可以“通信”以相互告知的某种方式,这样他们就不会尝试同时访问同一个文件时间。

【问题讨论】:

  • 同时访问文件不会导致死锁..它很可能会导致其他问题。 “更改保存路径”是什么意思?那只是更改文件使用的位置(例如变量),还是试图移动文件本身? (通常 windows 不允许移动打开的文件。)
  • 无论如何,如果这是我的程序——而且我仅限于这种通用设计——我将可以在“日志线程”上完成对文件的所有访问。主线程可以进行设置更改,但这样的更改只会在一个线程上处理。使用适当的线程安全性将此信息传递给日志记录线程仍然很重要,但这消除了多个线程(在同一程序内)在处理相同文件时奇怪地交互的问题。
  • “防止大量错误”的最常见方法是使用现有解决方案 - 周围有很多日志库。考虑澄清您的目标(据我所知,日志记录只是您尝试的一个示例),并显示您到目前为止所学内容的小样本,并突出显示您关注的地方。 (即,很难看出基本的lock 无法保护您的操作)
  • @user2864740 是的,位置是通过更改字符串变量来更改的。将其更改为仅由一个线程访问日志文件将需要进行一些代码检修(因为其他代码的工作方式)
  • @AlexeiLevenkov 我仍然了解锁,但我会更好地研究它们,看看我能做什么

标签: c# multithreading logging save


【解决方案1】:

你的问题把它引向了错误的方向,如果你解释你的最终目标是什么,你可能会得到更好的答案。

通常这是以不同的方式完成的。多个线程记录到内存缓冲区。每个线程都有自己的缓冲区,因此没有缓冲区争用。当线程的缓冲区已满时,会创建一个新缓冲区并与已满的缓冲区交换。记录继续到新缓冲区,而旧缓冲区被发送到一个线程,其目的只是将缓冲区写入文件并轮换日志文件。这允许多个线程非常快速地登录内存。由于只有一个线程实际与文件交互,因此文件移动操作不会发生冲突。

关于你的问题,假设文件移动不经常发生,你可以使用一个苗条的多读卡器,单写锁https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim%28v=vs.110%29.aspx 来实现这一点(如果你有多个线程记录并且只有一个移动文件),否则如果你只有两个线程,一个普通的 lock(obj) 语句就足够了。

【讨论】:

    【解决方案2】:

    只要你的主线程需要复制文件,我就会一起杀死你的日志线程,然后再启动一个新的日志线程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多