2011-02-08 88 views
0

我有一个写入的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

什么是“摇摆”? – siride 2011-02-08 17:18:30

+0

例外,错误,黑洞:-) – Jon 2011-02-08 17:22:14

+0

@Jon:但为什么“摇摆”?那是一种俚语俚语吗? – siride 2011-02-08 17:22:57

回答

2

这应该很好,因为它可以保护文件免受多个线程的并发访问。我唯一要做的就是将MyMethod中的两部分结合起来。没有理由在创建文件后释放锁,只是为了再次获得锁才能写入。因此,而不是:

lock 
{ 
    // Create file if necessary 
} 

lock 
{ 
    // write to the file 
} 

只要做到:

lock 
{ 
    // create file if necessary 
    // write to the file 
} 
1

我看到的唯一问题是,如果计时器触发并有0线进入它可以使一个不必要的文件,但可能是行为你要。

0

该代码看起来像它会工作,但如果效率是一个问题,我会去使用缓冲区和使用原子交换的路线来更改输出缓冲区的文件。

然后写入缓冲区不会涉及任何锁,只有写入文件会。

1

我不是专家,但只是一个想法。如果计时器在退出MyMethod中的第二个锁后直接触发将会发生什么情况。

private void MyMethod() { 
    lock{} 
    //Do processing 
    lock{} 
} 

它会尝试移动已移动的文件吗?