我需要咨询是否使用锁(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,因为这是一个很小的文件。
我应该使用锁,因为写入文件流需要一些时间吗?
我想知道计时器是否会引起问题(我不清楚计时器是否会抢占先机。)
谢谢您的建议。
答案 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)的评论来看,这将更具意义。