我有一个写入的StreamWriter。
当行数达到500时,它会关闭它并移动文件。
我已经添加了一个计时器,所以每隔5秒它关闭它并移动文件。
显然,如果计时器启动并关闭StreamWriter,然后在MyMethod中,它会尝试写入StreamWriter,它会抛出一个摇摆不定的状态。因此我添加了一些锁以尝试防止出现任何问题,因此如果计时器启动它会关闭StreamWriter,分配一个新的文件名,然后在锁定后如果MyMethod尝试写入它就全部应该没问题。
以下代码是否足以处理您认为的任何问题?
private readonly object objLock = new object();
private StartUpMethod()
{
if (tmFileWriter == null)
{
tmFileWriter = new Timer(5000);
tmFileWriter.AutoReset = false;
tmFileWriter.Elapsed += new ElapsedEventHandler(tmFileWriter_Elapsed);
}
}
private void MyMethod()
{
lock (objLock)
{
if (_tempFilename == "")
{
_tempFilename = GenerateFileName();
_tw = new System.IO.StreamWriter(_tempFilename);
}
}
//Do some processing
lock (objLock)
{
_tw.WriteLine(sql);
_filelineCount++;
if (_filelineCount > 500)
{
_tw.Close();
System.IO.File.Move(_tempFilename, _tempFilename.Replace(".tmp", ".sql"));
_tempFilename = "";
_filelineCount = 0;
}
}
private void tmFileWriter_Elapsed(object sender, ElapsedEventArgs e)
{
tmFileWriter.Stop();
lock (objLock)
{
if (_tw != null)
{
_tw.Close();
System.IO.File.Move(_tempFilename, _tempFilename.Replace(".tmp", ".sql"));
_tempFilename = GenerateFileName();
_tw = new StreamWriter(_tempFilename);
}
}
tmFileWriter.Start();
}
}
答案 0 :(得分:2)
这应该可以正常工作,因为它可以保护文件免受多个线程的并发访问。我唯一要改变的是将MyMethod
中的两个部分组合在一起。创建文件后没有理由释放锁定,这样您就可以再次获取锁定以进行写入。所以而不是:
lock
{
// Create file if necessary
}
lock
{
// write to the file
}
只是做:
lock
{
// create file if necessary
// write to the file
}
答案 1 :(得分:1)
我看到的唯一问题是,如果计时器触发并且输入了0行,则可能会生成不必要的文件,但这可能是您想要的行为。
答案 2 :(得分:1)
我不是专家,只是一个想法。如果计时器在退出MyMethod中的第二个锁后直接激活会发生什么。
private void MyMethod() {
lock{}
//Do processing
lock{}
}
它会尝试移动已移动的文件吗?
答案 3 :(得分:0)
代码看起来会起作用,但如果效率问题,我会选择使用缓冲区和使用原子交换来改变输出缓冲区的文件。
然后写入缓冲区不会涉及任何锁定,只会写入文件。