C#——安全的多线程保存文件访问
C# -- Safe Multiple Thread Save File Access
我目前正在开发一个 C# 应用程序,它使用两个单独的线程,第一个是主线程 程序在其上运行,第二个是 日志线程 。日志线程基本上是一个 循环,大约每秒运行一次 并且仅在应用程序关闭时中断。
基本上,如果有消息要输出,日志线程大约每隔一秒就会写入一个日志文件(文本文件)。我的问题是,在主线程上我有一个移动函数,它可以更改日志文件(和其他文件)的路径并将旧文件移动到新位置。我的问题是,如果日志线程正在写入日志文件并且移动函数试图移动文件,反之亦然,会发生什么情况?我将如何帮助防止这种情况发生?
如果我不更改保存路径,程序运行良好,但我担心如果主线程和日志线程同时尝试对日志文件执行某些操作,它们可能会死锁。我已经对此进行了一些研究,但我所能想到的是同时停止多个线程从 reading/writing 到一个文件的方法,而不是像我一样移动文件并写入它。所以真的,有没有什么方法可以让日志线程告诉主线程它正在使用日志文件,主线程可以在完成后使用日志文件,反之亦然?
多线程是我一直想尝试的东西,但总是被这样的复杂性所推迟。它当然需要更多的逻辑来阻止事情出错。
非常感谢您的帮助,因为这是应用程序为防止出现大量错误而需要做的最后一件事(至少我可以说,这才是测试的真正目的)。
编辑:
我真正想要的是两个线程在访问日志文件时可以"communicate"相互告知的某种方式,这样它们就不会尝试访问同时保存同一个文件。
每当您的主线程需要复制文件时,我会一起杀死您的日志线程,然后再启动一个新的日志线程。
你的问题引导了错误的方向,如果你解释你的最终目标是什么,你可能会得到更好的答案。
通常这是不同的做法。多个线程记录到内存缓冲区。每个线程都有自己的缓冲区,因此不存在缓冲区争用。当线程的缓冲区已满时,将创建一个新缓冲区并与已满缓冲区进行交换。日志记录继续到新缓冲区,而旧缓冲区被发送到一个线程,该线程的目的只是将缓冲区写入文件并轮换日志文件。这使得多个线程可以非常快速地登录内存。由于实际上只有一个线程与文件交互,因此文件移动操作没有冲突。
关于你的问题,假设文件移动不经常发生,你可以使用一个 slim multiple reader,一个 writer lock https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim%28v=vs.110%29.aspx 来实现这个(如果你有多个线程记录并且只有一个移动文件),否则如果你只有两个线程,一个简单的 lock(obj) 语句就足够了。
我目前正在开发一个 C# 应用程序,它使用两个单独的线程,第一个是主线程 程序在其上运行,第二个是 日志线程 。日志线程基本上是一个 循环,大约每秒运行一次 并且仅在应用程序关闭时中断。
基本上,如果有消息要输出,日志线程大约每隔一秒就会写入一个日志文件(文本文件)。我的问题是,在主线程上我有一个移动函数,它可以更改日志文件(和其他文件)的路径并将旧文件移动到新位置。我的问题是,如果日志线程正在写入日志文件并且移动函数试图移动文件,反之亦然,会发生什么情况?我将如何帮助防止这种情况发生?
如果我不更改保存路径,程序运行良好,但我担心如果主线程和日志线程同时尝试对日志文件执行某些操作,它们可能会死锁。我已经对此进行了一些研究,但我所能想到的是同时停止多个线程从 reading/writing 到一个文件的方法,而不是像我一样移动文件并写入它。所以真的,有没有什么方法可以让日志线程告诉主线程它正在使用日志文件,主线程可以在完成后使用日志文件,反之亦然?
多线程是我一直想尝试的东西,但总是被这样的复杂性所推迟。它当然需要更多的逻辑来阻止事情出错。
非常感谢您的帮助,因为这是应用程序为防止出现大量错误而需要做的最后一件事(至少我可以说,这才是测试的真正目的)。
编辑: 我真正想要的是两个线程在访问日志文件时可以"communicate"相互告知的某种方式,这样它们就不会尝试访问同时保存同一个文件。
每当您的主线程需要复制文件时,我会一起杀死您的日志线程,然后再启动一个新的日志线程。
你的问题引导了错误的方向,如果你解释你的最终目标是什么,你可能会得到更好的答案。
通常这是不同的做法。多个线程记录到内存缓冲区。每个线程都有自己的缓冲区,因此不存在缓冲区争用。当线程的缓冲区已满时,将创建一个新缓冲区并与已满缓冲区进行交换。日志记录继续到新缓冲区,而旧缓冲区被发送到一个线程,该线程的目的只是将缓冲区写入文件并轮换日志文件。这使得多个线程可以非常快速地登录内存。由于实际上只有一个线程与文件交互,因此文件移动操作没有冲突。
关于你的问题,假设文件移动不经常发生,你可以使用一个 slim multiple reader,一个 writer lock https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim%28v=vs.110%29.aspx 来实现这个(如果你有多个线程记录并且只有一个移动文件),否则如果你只有两个线程,一个简单的 lock(obj) 语句就足够了。