c#wpf中函数内的后台工作者

时间:2014-10-28 03:25:01

标签: c# backgroundworker

我在C#wpf中做了一个简单的gui,(抱歉,我无法显示GUI,因为我的声誉低于10)

它由richtextbox和其他一些控件组成。嗯...这个应用程序将读取一个文件,然后在使用后台工作程序读取文件时逐行显示文件内容到richtextbox。读取文件的函数如下:

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

正如我们所看到的,我在此函数中使用backgroundworker来获取从文件中获取的字符串,然后将该字符串发送到reportprogress以便在richtextbox中显示。请注意,persoFile2函数是从我的程序中的另一个对象...: - )

然后,对于其余部分,我已经使doWork函数,worker_progressChanged和worker_RunWorkerCompleted使backroundWorker正常工作。这些代码是这样的:

    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....");

    }

嗯....当我运行这个程序时,它看起来我的richtextbox不会从文件中逐行打印字符串,但它在结尾打印一次......:-3,.. Nah这是我真正的问题。我已经阅读了这篇文章http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx,但仍然不知道....:3

1 个答案:

答案 0 :(得分:1)

如果你过快地调用ReportProgress方法,那么UI线程可能没有机会处理“进度”并在BackgroundWorker再次点击之前适当更新。

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

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

要查看您期望的效果,可以在DoWork事件中设置一个人为的“暂停”,以便为UI提供适当更新的时间:

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

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

至于你的情况,如果代码快速执行,你实际上可能不需要在一个单独的线程中执行它。

或者,您可以更新您的用户界面,说“请等待。正在加载...”,然后在BackgroundWorker中执行您需要执行的所有操作,并在最后将最终结果返回给用户界面