@fill_n

Почему программа на С# при параллельном чтении одного и того же файла другой программой тихо завершается?

Есть две программы на С#, которые имеют доступ к одному XML файлу. Первая программа читает и пишет в файл раз в минуту, вторая читает этот файл раз в 5 минут. До установки второй программы первая спокойно себе записывала данные, но после установки стала иногда просто закрываться. Обе работают круглосуточно и поймать этот момент трудно.
Первая программа (которая вылетает) написана на WPF .NET Framework 4.5.2, вот часть кода, которая читает и пишет:
string fileName = Chart.GenerateDataBaseFileName(DateTime.Now);
            //Прочитать данные из файла, записать в DataSet.
            try 
            { 
                using (Stream s = File.Open(fileName, FileMode.OpenOrCreate)) dataSet_base.ReadXml(s); 
            } catch { }
            //Записать в DataSet текущие показатели датчиков.
            try
            {
                dataSet_base.Tables[0].Rows.Add
                (
                    DateTime.Now.ToString("t"),
                    KND_2.StateSensors.Tsens, KND_2.StateSensors.Psens,
                );
            }
            catch
            {
                MainWindow.AddStringToLogFile("Ошибка в сборе данных.");
            }
            //Записать полученные данные в файл.
            using (Stream s = File.Create(fileName)) try { dataSet_base.WriteXml(s); } catch { };

Вторая написана на .NET 5.0, вот метод, который читает:
//Прочитать данные из файла filePath, записать в dataSetObj. 
        //Вернет false, если словит исключение.
        private bool ReadXmlFromStream(ref DataSet dataSetObj, string filePath)
        {
            //Очистить данные, оставшиеся с предыдущей записи.
            dataSetObj.Clear();
            //Прочитать данные из файла, записать в DataSet.
            try
            {
                using Stream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                dataSetObj.ReadXml(stream);
                stream.Dispose();
            }
            catch
            {
                Console.WriteLine("catch ReadXmlFromStream");
                return false;
            }
            return true;
        }

FileShare.ReadWrite во второй программе - это попытка исправить вылеты первой, но это не помогло.
Если даже без выяснения причин вылетов, есть ли способы улучшить работу этих программ с одним файлом? Я подозреваю, что дело именно в конфликте программ. Вводить базу данных вместо XML я пока не готов.
  • Вопрос задан
  • 220 просмотров
Решения вопроса 1
@fill_n Автор вопроса
В обеих программах изменил открытие файла: добавил модификаторы доступа, убрал using. Уже около двух недель программа не вылетает. Вместо этого временами пишет в лог, что
Ошибка записи базы System.IO.IOException Процесс не может получить доступ к файлу "*.xml", так как этот файл используется другим процессом.
Что на работу программы не влияет. Поэтому можно считать, что баг устранен.
Вот как теперь выглядит код в первой программе, которая читает и пишет файл:
string fileName = Chart.GenerateDataBaseFileName(DateTime.Now);
            //Прочитать данные из файла, записать в DataSet.
            Stream readStream = null;
            try 
            {
                readStream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read);
                dataSet_base.ReadXml(readStream); 
            } 
            catch (Exception ex) 
            {
                MainWindow.AddStringToLogFile("Ошибка чтения базы " + ex.GetType() + " " + ex.Message);
            }
            finally
            {
                readStream?.Dispose();
            }
            //Записать в DataSet текущие показатели датчиков.
            try
            {
                dataSet_base.Tables[0].Rows.Add
                (
                    DateTime.Now.ToString("t"),
                    KND_2.StateSensors.Tsens, KND_2.StateSensors.Psens
                );
            }
            catch
            {
                MainWindow.AddStringToLogFile("Ошибка в сборе данных.");
            }
            //Записать полученные данные в файл.
            Stream writeStream = null;
            try
            {
                writeStream = File.Create(fileName);
                dataSet_base.WriteXml(writeStream);
            }
            catch (Exception ex)
            {
                MainWindow.AddStringToLogFile("Ошибка записи базы " + ex.GetType() + " " + ex.Message);
            }
            finally
            {
                writeStream?.Dispose();
            }
            //Сохранить настройки окна (все чекбоксы, настройки, выборы.)
            SaveDataSC(null, null);

А вот как во второй, которая только читает:
private bool ReadXmlFromStream(ref DataSet dataSetObj, string filePath)
        {
            //Очистить данные, оставшиеся с предыдущей записи.
            dataSetObj.Clear();
            //Прочитать данные из файла, записать в DataSet.
            Stream stream = null;
            try
            {
                stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write | FileShare.ReadWrite | FileShare.Delete);
                dataSetObj.ReadXml(stream);
            }
            catch(Exception ex)
            {
                stream?.Dispose();
                Console.WriteLine("catch {0} {1} {2}", DateTime.Now.ToString("G"), ex.GetType(), ex.Message);
                return false;
            }
            finally
            {
                stream?.Dispose();
            }
            return true;
        }
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
freeExec
@freeExec
Участник OpenStreetMap
FileShare.ReadWrite
Ты же сам заблокировал ей доступ на запись. И смысл пустых catch не понятен.
Ответ написан
mayton2019
@mayton2019
Bigdata Engineer
Тут - непонятно.
using Stream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

читающий поток разрешает другим одновременно запись. Это к чему. Чтобы разрушить файл?

А в пишущем потоке какие-то непонятные лишние действия совершаются. Зачем файл дваждый открывать-создавать?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы