Авто обновление файлов в C #? - PullRequest
0 голосов
/ 21 декабря 2010

В c # я создаю приложение на основе Thread, которое читает текстовый файл с компьютера (фактически удаленного компьютера), выбранного пользователем. если пользователь вносит какие-либо изменения в исходный файл, то это приложение должно отображать измененный файл (весь).

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

public partial class FormFileUpdate : Form
{
    // This delegate enables asynchronous calls for setting the text property on a richTextBox control.
    delegate void UpdateTextCallback(object text);

    // This thread is used to demonstrate both thread-safe and unsafe ways to call a Windows Forms control.
    private Thread autoReadThread = null;


    public FormFileUpdate()
    {
        InitializeComponent();

        //Creating Thread
        this.autoReadThread = new Thread(new ParameterizedThreadStart(UpdateText));
    }    

    private void openToolStripButton_Click(object sender, EventArgs e)
    {
        OpenFileDialog fileOpen = new OpenFileDialog();
        fileOpen.Title = "Select a text document";
        fileOpen.Filter = @"Text File|*.txt|Word Document|*.rtf|MS office Documnet|*.doc|See All files|*.*";
        fileOpen.FilterIndex = 1;
        fileOpen.RestoreDirectory = true;
        fileOpen.Multiselect = false;
        if (fileOpen.ShowDialog() == DialogResult.OK)
        {         
            //Created Thread will start here
            this.autoReadThread.Start(fileOpen.FileName);
        }
    }   

    private void UpdateText(object fileName)
    {    
        StreamReader readerStream = null;
        while(true)
        {
            if (this.richTextBox1.InvokeRequired)
            {
                UpdateTextCallback back = new UpdateTextCallback(UpdateText);
                this.Invoke(back, new object[] { fileName });
            }
            else
            {    
                try
                {
                    string fileToUpdate = (string)fileName;
                    readerStream = new StreamReader(fileToUpdate);
                    richTextBox1.Text = readerStream.ReadToEnd();
                }    
                catch (Exception ex) { MessageBox.Show(ex.Message); }    
                finally
                {
                    if (readerStream != null)
                    {
                        readerStream.Close();
                        Thread.Sleep(100);
                    }
                }
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 21 декабря 2010
  1. Вы выполняете чтение файла из потока GUI, что занимает много времени. Только обновление GUI должно быть сделано с началом вызова.
  2. Старайтесь не использовать while (true), вы можете использовать класс FileSystemWatcher для обновления экрана только при изменении файла (посмотрите здесь ).
0 голосов
/ 21 декабря 2010

Дополнительное примечание к тому, что написал Итай:

Вы звоните Thread.Sleep из потока GUI!Почему вам даже нужно сделать задержку после закрытия файла?Если вам нужна эта задержка по какой-либо причине (например, чтобы не читать файл слишком часто), не помещайте эту задержку в поток GUI, потому что это сделает ваше приложение не отвечающим.отвечая на ваш вопрос в комментарии

Возможным более чистым способом будет установка Timer, который будет вызывать BackgroundWorker каждые x секунд.

BackgroundWorker делаеточень легко запускать код в фоновом потоке и выполнять обратный вызов в потоке GUI, когда работа завершена.И вам не нужно иметь дело с Invoke и InvokeRequired напрямую.

Более того, я бы создал класс, который заключает в себе BackgroundWorker, чтобы было легче передавать данные из операции чтенияфайл (в фоновом потоке), для обновления пользовательского интерфейса (в потоке GUI).

...