【问题标题】:Background worker within a function in c# wpfc# wpf中函数内的后台工作者
【发布时间】:2014-10-29 00:26:04
【问题描述】:

我在 C# wpf 中做了一个简单的 gui,(对不起,我的声誉低于 10,所以无法显示 GUI)

它由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,..不这是我真正的问题。我已经阅读了这篇文章http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx,但仍然不知道......:3

【问题讨论】:

  • 我建议你应该使用 dispatcher.beginInvoke() 而不是 backgroundWorker
  • Waaaw.... 我添加了 System.Threading.Thread.Sleep(50);你说得对,格兰特先生。非常感谢... ;-)
  • 噢...我从来没有在 C# 中尝试过调度程序 Mr.Jadavparesh,我还是新手,但非常感谢您的建议... :-)

标签: c# backgroundworker


【解决方案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);
    }
}

就您的情况而言,如果代码执行得那么快,您实际上可能不需要在单独的线程中执行它。

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

【讨论】:

  • 是的......你是对的,格兰特先生,我在我的 while 循环中添加了 thread.sleep(50)。所以我现在可以看到reportProgress。嗯...关于“请稍等,正在加载...”,我认为这也是个好主意,但是如果我能看到richTextBox 从后台工作人员逐行更新,我会感到很高兴。呵呵... :-) 谢谢您的回答,格兰特先生... :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多