我刚刚重写了一个windows服务进程,它将重要信息调试输出到/programdata/myservice/文件夹中的一个日志文件中。
然而,在午夜时分,我有一个任务,它应该接受当前的日志文件并删除它的内容,然后创建一个包含日期的归档日志文件,日期为3天,例如LogfileArchived15092014.log。
然后运行一些代码来删除比这个日期更早的日志文件,所以我今天只有当前的日志文件,还有两个存档的日志文件,用于调试旧的问题等等。
现在,我已经从正在工作的旧服务中复制了执行此操作的代码,并将日志文件归档并删除旧的日志文件。但是,由于某些原因,当这个新作业运行时,我会得到I/O错误,如以下(来自事件查看器)
运行系统作业: I/O错误归档日志文件: C:\ProgramData\Brainiac\LogfileArchived;进程无法访问文件'C:\ProgramData\Brainiac\Logfile.log‘,因为它正在被其他进程使用。
现在,第一条路径没有扩展名(例如C:\ProgramData\Brainiac\LogfileArchived )的原因是,在文件日期被创建以附加到文件名(例如)之前,它显然被抛出了一个错误。
// set a lock up to prevent other processes locking
this.Locked = true;
// wrap in try as it keeps failing!!!!
try
{
// take contents of current log file - the daily one I have been logging to all day
// I guess this is where the error is being raised due to the absence
// of a .log extension in the error message when mentioning the filename
string content = this.ReadFileString(this.logFilePath);
// for some reason todays log file was empty
// why would this be unless loggging was disabled?
if (!String.IsNullOrEmpty(content))
{
// create a new log file with date stamp of yesterday added to the filename and guff removed to make it valid
string file_date = DateTime.Now.Date.AddDays(-1).ToString().Replace("/", "").Replace("-", "");
// remove time part - should be done at midnight but if not ensure colons and spaces are removed
file_date = file_date.Replace("00:00:00", "").Replace(":", "").Replace(" ", "");
// append .log to it
this.logfilearchivepath += file_date + ".log";
//Append all the contents of my daily log file to this new file
File.AppendAllText(this.logfilearchivepath, content, Encoding.UTF8);所以我怀疑它是在这条线上爆炸
string content = this.ReadFileString(this.logFilePath);由于错误消息中没有扩展名。所以也许我需要一种不同的方式来访问内容?
现在我不知道它还锁定了什么进程(我能不知怎么发现吗?)但我试过以下几种方法。
在我进行日志记录的方法中,我检查它是否能够尽快退出,例如
// log to our application data folder - unless locked for some reason
public void LogMsg(string msg, string debugLevel = "HIGH")
{
// we are prevented from logging at this point in time
if (this.Locked) return;因此,我有一个名为LOCKS的表和用来插入/删除一个锁记录的方法,还有一个检查不存在的方法。
因此,如果多个进程尝试从不同的应用程序同时运行相同的代码,那么它就不应该能够运行,因为数据库中将存在锁记录,该数据库将在作业开始运行之前插入并在作业完成后删除(正在运行的锁)。
此外,一旦完成,将插入一个LOGFILE_ARCHIVED锁记录,以便相同或不同的作业知道日志文件已经归档,并且不再试图将其存档。
我在锁文件中使用计算机名称,因为进程可以在任何时候在多台服务器/计算机上运行。
那么,我还能做些什么来解决这个问题呢?
我是否应该使用不同的方法来获取不会被锁定文件所阻止的日志文件内容(我不知道锁在做什么,但是this.Locked = True应该防止在归档工作期间记录到文件中的任何内容),但是文件上的“锁”显然比我的代码要高。
这是在Win 7机器上用C# .NET 4.5编写的windows服务。
谢谢你的帮助。
发布于 2014-09-17 16:45:10
我让它起作用了。我刚刚遇到了一个问题,this.Locked在Helper类中,以及调用DLL的其他并发实例中,忽略了它(多线程问题),所以我将我的DB检查放到了帮助类的类中,所以
this.Locked = this.GetCurrentLockedStatus();然后任何进程都会得到相同的值。这意味着在文件传输期间没有日志记录,因为在尝试执行该记录和退出任何LogMsg方法之前,我都会在其中添加锁记录。
this.Locked = true;现在它就像一种魅力。我真的不知道为什么旧的服务是有效的。我可以在事件日志中看到很多I/O错误,但最终它只是出于某种原因成功地做到了这一点。这种使用DB维护锁的方法似乎更好、更快。
谢谢你的帮助。
https://stackoverflow.com/questions/25868412
复制相似问题