C#中的自动文件更新程序?

时间:2010-12-21 11:53:21

标签: c# multithreading c#-4.0 thread-safety

在c#i中创建基于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 个答案:

答案 0 :(得分:1)

  1. 您正在从GUI线程中读取文件,这是一项耗时的操作。只应使用begin invoke完成GUI更新。
  2. 尽量不要使用while(true),只有在文件发生变化时才能使用FileSystemWatcher类来更新显示(看看here)。

答案 1 :(得分:0)

对Itay写的补充说明:

您正在从GUI线程调用Thread.Sleep!为什么你在关闭文件后甚至需要延迟?如果由于某种原因确实需要此延迟(例如,为了避免过于频繁地读取文件),请不要将此延迟放在GUI线程上,因为这会使您的应用程序无响应。

编辑:在评论中回答您的问题

一种可能更简洁的方法是设置Timer,每x秒调用一次BackgroundWorker

BackgroundWorker使得在后台线程中运行代码变得非常容易,并且在工作完成时在GUI线程上运行回调。而且您无需直接处理InvokeInvokeRequired

此外,我将创建一个包装BackgroundWorker的类,以便于从读取文件的操作(在后台线程中)传递数据到更新UI(在GUI线程中)。