C#写入/读取文件,我应该使用锁吗

时间:2018-09-24 19:03:45

标签: c# winforms file timer

我需要咨询是否使用锁(ReaderWriterLockSlim)。

用户在屏幕上进行交互,并且可以将数据保存到文件中:

XmlSerializer xmlserializer = new XmlSerializer(typeof(MyFile));
FileStream fs = new FileStream(fileName, FileMode.Create,FileAccess.ReadWrite);
xmlserializer.Serialize(fs, this);
fs.Close();

并行地,我有一个计时器(因此是同一线程,System.Windows.Forms.Timer),该计时器检查相同的文件大小并将其发送到服务器(如果已修改)。 我将使用File.ReadAllBytes,因为这是一个很小的文件。

我应该使用锁,因为写入文件流需要一些时间吗?

我想知道计时器是否会引起问题(我不清楚计时器是否会抢占先机。)

谢谢您的建议。

1 个答案:

答案 0 :(得分:4)

在WinForms中,事件永远不会中断在同一线程(即UI线程)中运行的运行方法。任何timer_Tick(来自System.Windows.Forms.Timer)都将延迟,直到序列化代码完成为止。

(我假设您没有使用异步调用。)

在关闭文件之前,您可以直接从FileStream读取文件大小。

var xmlserializer = new XmlSerializer(typeof(MyFile));
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) {
    xmlserializer.Serialize(fs, this);
    Console.WriteLine(fs.Length); // <=========
} // The using-statement automatically closes fs

如果您需要知道文件是否在另一个例程中发生了更改,为什么不只使用标志呢?

public static bool FileHasChanged { get; set; }

...

var xmlserializer = new XmlSerializer(typeof(MyFile));
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) {
    xmlserializer.Serialize(fs, this);
}
FileHasChanged = true;

在另一个例行程序中(我认为timer_Tick):

if (MyFile.FileHasChanged) {
    //TODO: Send file to server.
    MyFile.FileHasChanged = false;
}

由于所有内容都在同一线程中运行,因此不需要锁定。


另一个问题是您是否真的需要文件,或者是否可以只写到MemoryStream,然后使用此内存流将数据发送到服务器。如果仍然需要该文件,则可以使用相同的内存流对其进行写入,并且仅序列化一次。内存流将替换布尔标志,用于两个例程之间的通信。发送到服务器后,将在调用null(而不是Dispose())后将内存流设置为MyFile.FileHasChanged = false;

从埃里克·利珀特(Eric Lippert)的评论来看,这将更具意义。