PawanS
PawanS

Reputation: 7193

Auto file updater in C#?

In c# i m creating a application based on Thread, that read a text file from Computer(actually remote computer) selected by user. if user makes any changes in original file then this application should display the modified file(whole).

Successfully its doing but, thread that I am using don't know how and where to place that it continuous read the original file from background. My application gets hangs with this code

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);
                    }
                }
            }
        }
    }
}

Upvotes: 0

Views: 430

Answers (2)

Ran
Ran

Reputation: 6159

Additional note to what Itay wrote:

You are calling Thread.Sleep from the GUI thread! Why do you even need to make a delay after closing the file? If you do need this delay for some reason (e.g. to avoid reading the file too frequently), don't put this delay on the GUI thread, because this will make your application unresponsive.

EDIT: answering your question in the comment

A possible cleaner way would be to set a Timer which would invoke a BackgroundWorker every x seconds.

The BackgroundWorker makes it very easy to run code in a background thread, and to have a callback run on the GUI thread when the work is completed. And you don't have to deal with Invoke and InvokeRequired directly.

Furthermore, I would create a class which wraps a BackgroundWorker to make it easy to pass data from the operation of reading the file (in the background thread), to updating the UI (in the GUI thread).

Upvotes: 0

Itay Karo
Itay Karo

Reputation: 18286

  1. You are making the file read from the GUI thread which is a time consuming action. Only the GUI update should be done with begin invoke.
  2. Try not to use while(true), you can use the FileSystemWatcher class to update the display only when the file changes (Take a look here).

Upvotes: 1

Related Questions