C # Запись / чтение файла, должен ли я использовать блокировку - PullRequest
0 голосов
/ 24 сентября 2018

Мне нужен совет, независимо от того, используется ли блокировка (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 голосов
/ 24 сентября 2018

В WinForms событие никогда не прерывает работающий метод, запущенный в том же потоке (то есть в потоке пользовательского интерфейса).Любой 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;).

Это было бы больше в смысле комментариев Эрика Липперта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...