在我详细介绍之前,我的程序是使用C#.Net 4.0在Visual Studio 2010中编写的。
我写了一个程序,它会为每次运行生成单独的日志文件。日志文件以时间命名,精确到毫秒(例如, 20130726103042375.log )。如果该日期尚不存在,该程序还将生成当天的主日志文件(例如,* 20130726_Master.log *)
在每次运行结束时,我想将日志文件附加到主日志文件中。有没有办法检查我是否可以成功追加?并在Sleep
之后重试一段时间或什么?
基本上,我有1个可执行文件和多个用户(假设有5个用户)。
所有5个用户将同时访问并运行此可执行文件。由于所有用户几乎不可能在完全相同的时间(最多毫秒)启动,因此生成单个日志文件没有问题。
但是,当我尝试将这些日志文件合并到主日志文件时,会出现此问题。虽然不太可能,但我认为如果多个用户附加到同一主日志文件,程序将崩溃。
我使用的方法是
File.AppendAllText(masterLogFile, File.ReadAllText(individualLogFile));
我已经检查了lock
对象,但我认为它在我的情况下不起作用,因为在一个实例中有多个实例而不是多个线程运行。
我研究的另一种方式是try/catch
,类似这样的
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch {}
但我不认为这可以解决问题,因为masterLogFile的状态可以在那么短的毫秒内改变。
所以我的整体问题是:如果没有使用,是否可以附加到masterLogFile,如果是,则在短暂超时后重试?或者,如果有另一种方法来创建masterLogFile?
提前谢谢你,对不起这条长信息感到抱歉。我想确保收到我的信息并解释我尝试或调查过的内容,这样我们就不会浪费任何人的时间。
如果我能提供更多信息来帮助您,请告诉我。
答案 0 :(得分:0)
你的尝试/捕获是做事的方式。如果对File.Open
的调用成功,则可以写入该文件。我们的想法是保持文件打开。我会建议像:
bool openSuccessful = false;
while (!openSuccessful)
{
try
{
using (var writer = new StreamWriter(masterlog, true)) // append
{
// successfully opened file
openSuccessful = true;
try
{
foreach (var line in File.ReadLines(individualLogFile))
{
writer.WriteLine(line);
}
}
catch (exceptions that occur while writing)
{
// something unexpected happened.
// handle the error and exit the loop.
break;
}
}
}
catch (exceptions that occur when trying to open the file)
{
// couldn't open the file.
// If the exception is because it's opened in another process,
// then delay and retry.
// Otherwise exit.
Sleep(1000);
}
}
if (!openSuccessful)
{
// notify of error
}
因此,如果您无法打开文件,请进入睡眠状态并重试。
有关详细信息,请参阅我的博客文章File.Exists is only a snapshot。
答案 1 :(得分:0)
我会按照this的方式做一些事情,因为我认为这会产生最少的开销。如果抛出异常,Try / catch将生成堆栈跟踪(可能需要一整秒)。必须有更好的方法来原子地做这个。如果我找到一个,我会发布它。