Sigmond Gatt Ответов: 2

Обновить форму в winform C#


привет ребята,

Прямо сейчас я читаю из файла и генерирую некоторую статистику

ниже приведен код :



static FileSystemWatcher _watcher;

       static void Init()
       {
           //Adding a watcher to the following directory to know when there is a change.
           string directory = //path to directory";
           MainPage._watcher = new FileSystemWatcher(directory);
           MainPage._watcher.Changed += new FileSystemEventHandler(MainPage._watcher_Changed);
           MainPage._watcher.EnableRaisingEvents = true;

       }


       static void _watcher_Changed(object sender, FileSystemEventArgs e)
       {
           //reload MainPage to update statistics.

       }



       private void MainPage_Load(object sender, EventArgs e)
       {


           OperationClass oc = new OperationClass();
           oc.LoadFileForGenerationData();
           List<string> username = oc.gettingUserData();
           List<int> amountoftrn = oc.getAmountOfTrn();
           fillChart(username, amountoftrn);



           //LABELS
           List<int> counters = oc.LoadFileForNumberOfErrors();

           lblTotalNumberOfUsers.Text = username.Count().ToString();
           lblTotalNumberOfTrns.Text = amountoftrn.Sum(x => Convert.ToInt32(x)).ToString();

           lblErrors.Text = counters[0].ToString();
           lblFatals.Text = counters[1].ToString();
           lblWarnings.Text = counters[2].ToString();


           //filestreamWatcher
           Init();

       }



       private void fillChart(List<string> username, List<int> amountoftrn)
       {


           TransactionChart.Titles.Add("Transaction Chart");
           //                                                  //name of user , number of transactions
           int i = 0;
           foreach (var uname in username)
           {
               TransactionChart.Series["Transactions"].Points.AddXY(username[i], amountoftrn[i]);
               i++;
           }



       }



Итак, у меня есть FileSystemWatcher в каталоге, поэтому, когда в этом каталоге произойдет изменение, я перезагрузлю mainform, чтобы метод _load снова запустился и статистика была обновлена.
--------------------------------------------------------------
ОБНОВЛЕНИЕ:
Я сделал новое обновление благодаря ДВ@Зи .
- Изменен метод filewatcher на нестатический
- сделал метод, поместил в него содержимое _load и вызвал его из _changed и _load

Новая проблема заключается в том, что когда я пытаюсь перезагрузить статистику, исключение ввода-вывода остается необработанным. это следующий код, в котором происходит сбой программы (в строке "using):
using (var filestream = new FileStream("//path to file.", FileMode.Open, FileAccess.Read,FileShare.None))
{
    MyTextFileDataSet.ContentExpression = new Regex(@"^(?<date>[^ ]+) (?<time>[^A-Z]+) (?<errorMessage>[^[]+) \[1\] (?<programName>[^.]+)[.](?<formName>[^.]+)[.](?<event>[^ ]+)[^a-z]+(?<username>[^:]+):(?<message>[^.]+).+$", RegexOptions.Multiline);

    MyTextFileDataSet.Fill(filestream);
    filestream.Flush();
    //filestream.Close();
    filestream.Dispose();
}

----------------------------------------------------------

Если есть какие-то проблемы или вы не поняли, не стесняйтесь комментировать.

Что я уже пробовал:

Я попробовал несколько методов, чтобы перезагрузить главную страницу (Я получил только 1 форму.)

Главная страница.ActiveForm.Распоряжаться()
MainPage frm = новая главная страница()
ФРМ.Показать()

---------
MainPage frm = новая главная страница()
frm.refresh(), перезагрузка.....

при попытке избавиться от исключения nullreference было дано исключение.. Может ли кто-нибудь сказать мне, что я могу сделать, или, может быть, есть обходной путь ?

-----------------------------------------------------------------
ОБНОВЛЕНИЕ ТОГО, ЧТО ВЫ ПРОБОВАЛИ:
Я попытался chnage файловый ресурс для ReadWrite, но затем возникает проблема, когда я пытаюсь войти в систему с помощью log4net из другого решения.
может быть, это может вам помочь, это приложение.config log4net.

<log4net>
    <root>
    <level value="DEBUG" />
    <appender-ref  ref="TestAppender" />
  </root>
  <appender name="TestAppender" type="log4net.Appender.RollingFileAppender">
    <lockingmodel type="log4net.Appender.FileAppender+MinimalLock"/>
    <param name="File" value="//same path of the filestream." />
    <param name="AppendToFile" value ="true"/>
    <encoding value="utf-8" />
    <rollingStyle value="Date" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level [%thread] %type.%method   %message%n" />
    </layout>
  </appender>

</log4net>

Кто-нибудь может сказать мне, что я могу сделать ?
---------------------------------------------------

FranzBe

Нет необходимости перезагружать всю форму целиком. Вам просто нужно обновить некоторые данные, которые отображаются в форме. Сделайте частный метод void ReloadStatistics (), поместите в него соответствующий код из события MainPage_Load. Вызовите новый метод из MainPage_Load() , а также из _watcher_changed().

Sigmond Gatt

пожалуйста , смотрите комментарий к решению 1, может быть, вы можете мне помочь, пожалуйста :)

2 Ответов

Рейтинг:
16

lw@zi

Я не могу понять, как вы используете данные каталога/файла. Возможно, класс эксплуатации это. В этом случае, если вы можете отделить код в обработчике событий load и вызвать этот метод из обработчиков событий для FileSystemWatcher.

Обновление:

Есть несколько вещей, которые вы должны изменить в коде (без каких-либо знаний об альтернативном процессе, работающем с тем же файлом).

1. В конструкторе FileStream, вы устанавливаете FileShare к None Это в основном означает, что ни один другой процесс не может ничего сделать с файлом, пока этот поток не будет закрыт. В вашем случае, поскольку вы только читаете файл, я бы предложил установить его в ReadWrite.
2. Вы используете using блок. Это означает, что FileStream будет удален автоматически, как только управление выйдет из блока. Вам не нужно звонить Dispose метод.
3. Вы также используете Flush метод, который опять же не нужен, так как вы не пишете в файл.

Вы можете протестировать свой код после внесения изменений и посмотреть, все ли работает так, как ожидалось.

Кроме того, если у вас есть еще какой-то вопрос по другой проблеме, было бы лучше опубликовать его как еще один вопрос, чтобы ограничить его текущей темой. Для обсуждение стиль проработки проблемы, ИМХО, соответствующий CP-форуму, можно было бы использовать.


Sigmond Gatt

я уже пробовал это сделать, но это не позволит мне, так как метод должен быть статичным.
Когда я попытался поставить метод статическим, он не позволил мне обновить метки и т. д...

Может быть, вы мне поможете, пожалуйста ? извините за спам

Sigmond Gatt

Я попробовал то, что вы мне сказали, и это ошибка :
для этого нестатического поля, метода или объекта 'MainPage.generatingStatistics()'требуется ссылка на объект

может быть, мне нужно вызвать этот метод ?? не знаю, просто спрашиваю.

lw@zi

Я вижу, что ваши обработчики событий для FileSystemWatchers помечены как статические. Есть какая-то конкретная причина для этого? Вы можете удалить из них статическое ключевое слово.

Sigmond Gatt

привет извините за спам, в одном из моих методов у меня есть этот код :

public List<int> LoadFileForNumberOfErrors()        {            var MyTextFileDataSet = new TextFileDataSet.TextFileDataSet();            using (var filestream = new FileStream("//Path to file", FileMode.Open, FileAccess.Read,FileShare.None))            {                MyTextFileDataSet.ContentExpression = new Regex(@"^(?<date>[^ ]+) (?<time>[^A-Z]+) (?<errorMessage>[^[]+) \[1\] (?<programName>[^.]+)[.](?<formName>[^.]+)[.](?<event>[^ ]+)[^a-z]+(?<username>[^:]+):(?<message>[^.]+).+$", RegexOptions.Multiline);                MyTextFileDataSet.Fill(filestream);                filestream.Flush();                filestream.Dispose();            }


что я могу сделать, как когда я пытаюсь перезагрузить статистику и IOException не обрабатывается, может быть, вы можете мне помочь, пожалуйста? как я уже сказал извините за спам

lw@zi

Можете ли вы обновить вопрос этими деталями вместо раздела комментариев? Так будет лучше для будущих читателей.

Sigmond Gatt

я только что обновил решение прямо сейчас. Если есть какие - то проблемы, не стесняйтесь спрашивать :)

lw@zi

Обновленный ответ.

Рейтинг:
12

FranzBe

возможно, вы можете использовать это в качестве отправной точки и разработать его для своих нужд

public partial class Form1 : Form
 {
   private FileSystemWatcher _watcher;
   private System.Threading.Tasks.TaskScheduler _uiScheduler;
   public Form1()
   {
     InitializeComponent();
   }

   protected override void OnLoad(EventArgs e)
   {
     base.OnLoad(e);
     _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
     InitFileSystemWatcher();
   }

   private void ReloadStatistics(FileSystemEventArgs e)
   {
     // use some sort of InvokeRequired here to update the Control in the UI-Thread
     Task.Factory.StartNew(() =>
     {
       string message = $"{DateTime.Now} : {e.Name}-{e.ChangeType}";
       label2.Text = message;
     }, CancellationToken.None, TaskCreationOptions.None, _uiScheduler);
   }

   private void InitFileSystemWatcher()
   {
     string directory = @"c:\temp"; //path to directory";
     _watcher = new FileSystemWatcher(directory);
     _watcher.Changed += new FileSystemEventHandler(OnWatcherChanged);
     _watcher.EnableRaisingEvents = true;
   }

   private void OnWatcherChanged(object sender, FileSystemEventArgs e)
   {
     ReloadStatistics(e);
   }
 }


Sigmond Gatt

привет спасибо вам за ваше решение , небольшой вопрос : какова цель taskscheduler ?

FranzBe

Обратный вызов из FileSystemWatcher не выполняется в потоке пользовательского интерфейса, поэтому вы не можете обновить элемент управления, когда находитесь в методе OnWatcherChanged (). Существуют различные способы справиться с этим (поиск "InvokeRequired") в приведенном выше примере я запускаю новую задачу, которая выполняется в потоке пользовательского интерфейса, TaskScheduler.FromCurrentSynchronizationContext() заботится о том, чтобы использовался правильный поток.

Sigmond Gatt

я проверю это :) большое вам спасибо :)