C#写/读文件,我应该使用锁吗
我需要建议是否使用锁(ReaderWriterLockSlim) 用户在屏幕上进行交互,数据可以保存到文件中:C#写/读文件,我应该使用锁吗,c#,winforms,file,timer,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(); 同
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,因为这是一个相当小的文件
写文件流需要一些时间,我应该使用锁吗
我想知道计时器是否会导致问题(我不清楚它是否会抢先)
感谢您的建议。在WinForms中,事件不会中断在同一线程(即UI线程)中运行的方法。任何
timer\u勾选
(来自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
在另一个例程中(timer\u Tick
我想):
因为所有东西都在同一个线程中运行,所以不需要锁定
另一个问题是您是否真的需要一个文件,或者您是否可以只写一个文件,然后使用这个内存流将数据发送到服务器。如果仍然需要该文件,则可以使用相同的内存流对其进行写入,并仅序列化一次。内存流将替换两个例程之间通信的布尔标志。发送到服务器后,调用
Dispose()
(而不是MyFile.FileHasChanged=false;
)后,内存流将设置为null
这更符合埃里克·利珀特的评论。哇,退一步。究竟为什么要使用
ReadAllBytes
来获取文件的长度,而不是FileInfo.length
?如果我问你一本书有多少页,你不必读这本书就能知道!是因为您需要将字节发送到服务器吗?假设还有另一个进程也在写入文件。在那种情况下,你使用读写器锁的想法是行不通的!您不需要跨线程锁,您需要跨进程锁。文件已经提供了这一功能,这意味着您需要确保在尝试读取或写入文件时正确处理文件被锁定的情况。你这样做了吗?如果文件改变了内容但没有改变大小呢?这整件事对我来说似乎非常狡猾。如果没有其他进程和线程,那么为什么你需要检查任何东西来知道文件是否被修改?你在做改变,所以你知道。如果所有的东西都在一个线程上,那么为什么你会认为你需要一个线程锁呢?如果你让一个线程进入睡眠状态,等待它自己完成一项工作,那么显然它将永远处于睡眠状态!这个问题让人困惑。是你说你需要任何建议,我给了你很多好的建议。如果你不想得到建议,就不要征求!听起来这个设计有很多你可能没有想到的问题;现在是仔细考虑它们的好时机。非常感谢,我不确定。非常感谢,我不确定。我觉得能够处理TCP套接字进行通信很愚蠢(因此锁很有用),但对这个简单的计时器不太确定。。。正如我在另一条评论中所写,我使用File.Readallbytes通过套接字发送文件(如果大小不同),而不是检查文件大小。我的英语很差,我只想记下我使用的阅读功能。谢谢所有有价值的评论和建议。
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;
if (MyFile.FileHasChanged) {
//TODO: Send file to server.
MyFile.FileHasChanged = false;
}