2016-09-09 49 views
0

您好,感谢您的帮助。 这次我遇到一个好奇的问题,我正在写一个程序(C#),并希望听到您的建议。 我正在写一个正常的程序(不是多线程),但随后添加了一个计时器(System.Timers.Timer)定时器,文件和竞态条件?

另外我正在使用StreamWriter写入文件。我这样打开这个

StreamWriter logStream=new StreamWriter(filename, true); 

这意味着如果文件存在,它会追加,如果没有创建。

后来我写在文件中这样

logStream.WriteLine(message); 

不过,我写到流从的主要功能和由定时器调用的函数。

问题症状

我的程序有时会抛出一个错误,当我刷新或写入流说,“无法访问已关闭的文件”等次“无法访问已关闭的TextWriter ... (什么是“TextWriter的”?)

然而奇怪的是,该文件不断被写入没有问题。(即使是“无法访问已关闭的文件”的消息被写入应该关闭的文件)

我不熟悉定时器的内部工作(我想它运行一个sep arate线程?)

我的问题是

是否有可能使用一个StreamWriter从多个线程? (在这种情况下,主要和定时器之一) 是否有可能发生竞争条件或类似的问题?


一两件事:我犯了一个逻辑错误,接近,我想在上面写,每次打开文件。是的,这是一个错误,我应该纠正它。但是,也许如果我纠正了这个错误,我上面描述的错误将消失掩盖更严重的缺陷。

我的怀疑是因为我关闭和打开文件时间我写上,也许是两个线程试图访问他们在错误的时间

任何帮助,将不胜感激

+0

您的其中一个问题:StreamWriter是一个特定的TextWriter。 –

+2

你想创建一个日志实现吗?你为什么不使用。NET的内置诊断API或log4net等日志库?日志记录库必须接受来自多个线程的日志请求,但必须正确写入所有条目而不会破坏日志文件。 –

回答

1

在这种情况下关闭并打开文件将创建一个像您怀疑的竞争条件。您不能保持流打开并将对象传递给线程,因为如果您从不同的线程调用,最终可能会出现类似的问题。您的最佳解决方案仍然使用线程安全的方法,将写入您发送给它的内容。

这些方法是静态的,因为锁必须可以从类的所有实例访问。

private static ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim(); 

public static void AppendToFile(string path, string text) 
{ 
    // Set to locked (other thread will freeze here until object is unlocked 
    readerWriterLockSlim.EnterWriteLock(); 

    try 
    { 
     // Write that will append to the file 
     using (StreamWriter sw = File.AppendText(path)) 
     { 
      // append the text 
      sw.WriteLine(text); 
      sw.Close(); 
     } 
    } 
    finally 
    { 
     // Clear the lock 
     readerWriterLockSlim.ExitWriteLock(); 
    } 
} 
+1

更好的是,使用日志库。或者ActionBlock 将来自多个线程的消息排队并使用简单的写入器逐个写入 –