简体   繁体   中英

Background worker within a function in c# wpf

I have made a simple gui in C# wpf, (sorry I can't show the GUI because my reputation is below 10)

It's consist of richtextbox and some other controls. Umm... this application will read a file then display the file contents to richtextbox line by line while reading the file using background worker. The function that read the file is like this :

    public int parse_persoFile2(string fname, BackgroundWorker worker, DoWorkEventArgs e)
    {
        if (fname == null) return -1;
        System.IO.StreamReader ifs;
        ifs = new System.IO.StreamReader(fname);

        int max = (int)e.Argument;
        int p = 0;

        while (ifs.Peek() != -1)
        {
            string tempData = ifs.ReadLine();

            if (tempData.Contains("CMD=5107") || tempData.Contains("CMD=5106") || tempData.Contains("CMD=5102"))
            {

                //field.AppendText(tempData.Remove(tempData.LastIndexOf('\\')).Remove(0, 4) + "\r\n");
                //field.AppendText("--------\r\n");
                //System.Threading.Thread.Sleep(500);
                string data = tempData.Remove(tempData.LastIndexOf('\\')).Remove(0, 4) + "\r\n";
                worker.ReportProgress(p, data);
            }

            p++;

        }
        worker.ReportProgress(100);
        return 0;
    }

As we can see, I'm using backgroundworker in this function to get the string readed from file then send that string to reportprogress in order to be displayed in richtextbox. As a note that persoFile2 function is made from another object in my program... :-)

Then for the rest, I have made the doWork function, worker_progressChanged, and worker_RunWorkerCompleted to make backroundWorker works correctly. Those codes are like this :

    private void doWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker wrk = sender as BackgroundWorker;
        parser.parse_persoFile2(fileName, wrk, e);
    }

    private void proggChanged(object sender, ProgressChangedEventArgs e)
    {
        if(e.UserState != null)
        mRTB.AppendText(e.UserState.ToString());
    }

    private void completed(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Ok....");

    }

Umm.... When I run this program, it looks that my richtextbox is not prints the string line by line from the file, but it prints it just once at the end... :-3, .. Nah that's my real problem here. I have read this article http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx , but still have no idea.... :3

If you call the ReportProgress method too rapidly, it's possible that the UI thread will not have a chance to process the "progress" and update appropriately before the BackgroundWorker is hitting it again.

private void doWork(object sender, DoWorkEventArgs e)
{
    var wrk = sender as BackgroundWorker;

    // obviously you wouldn't really do this :)
    while(true)
        wrk.ReportProgress(0);
}

To see the effect you're looking expecting, you could set an artificial "pause" in your DoWork event, in order to give the UI time to update appropriately:

private void doWork(object sender, DoWorkEventArgs e)
{
    var wrk = sender as BackgroundWorker;

    var p = 0;
    while(true)
    {
        wrk.ReportProgress(p++);
        Thread.Sleep(100);
    }
}

As for your situation, if the code is executing that quickly, you may not actually need to be executing it in a separate thread.

Alternatively, you could update your UI to say "Please wait. Loading...", then do everything you need to do in the BackgroundWorker , and just return the final result back to the UI at the end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM