TextBox未通过启用了DataReceivedEventHandler的BackgroundWorker实时更新

时间:2017-01-10 19:27:44

标签: c# multithreading backgroundworker

我需要一些BackgroundWorker的帮助。使用Visual Studio 2015及其窗体

我对这类事情不熟悉并且真的不知道它是如何工作的。我到目前为止的代码基于这里的各种帖子。

worker_DoWork_根本没有被解雇,但不知道为什么。我相信这与DataRceivedEventHandler有关,因为当我移动If我移动worker.DoWork + = worker_DoWork_;和worker.RunWorkerAsync();进入按钮单击事件并禁用DataReceivedEventHandler,方法worker_DoWork_被触发,我可以使用在DoSomeWork下分配的任何静态文本更新textBox。

另外,我不知道如何通过DoSomeWork将大纲数据传递到文本框中。

请有人帮帮忙。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;


namespace CMD_testing
{
  public partial class Form1 : Form
  {
    BackgroundWorker worker;
    private delegate void DELEGATE();

    public Form1()
    {
        InitializeComponent();
        worker = new BackgroundWorker();
    }

    private void button2_Click(object sender, EventArgs e)
    {

        Process process;
        process = new Process();
        process.StartInfo.FileName = @"C:\\Project\Test\Data.bat";
        process.StartInfo.UseShellExecute = false;
        //   process.StartInfo.CreateNoWindow = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);

        process.StartInfo.RedirectStandardInput = true;
        process.Start();
        process.BeginOutputReadLine();
       // process.WaitForExit();
        // process.Close();
    }

    private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        if (outLine.Data != null)
        {
            Console.WriteLine("Im here...");

            worker.DoWork += worker_DoWork_;
            //worker.RunWorkerAsync();
            Console.WriteLine("Im here NOW");

            Console.WriteLine(outLine.Data);  //its outputed fine into the console 
        }

    }

    private void worker_DoWork_(object sender, DoWorkEventArgs e)
    {
        Console.WriteLine("I'm at worker_DoWork_");
        Delegate del = new DELEGATE(DoSomeWork);
        this.Invoke(del);
    }

    private void DoSomeWork()
    {
        Thread.Sleep(1000);
        textBox1.Text = "????";  // how to pass outline.Data in here

    }

}

}

2 个答案:

答案 0 :(得分:0)

问题是你勾勒出RunWorkerAsync();。此方法触发处理异步代码的DoWork-Event。通过DoWork的EventArgs,您可以将结果重新使用回主线程并将其打印到文本框中。您可以在RunWorkerCompleted-Event中获取结果。这是一个基于代码的小例子:

  public partial class Form1 : Form
  {
    BackgroundWorker worker;

    public Form1()
    {
        InitializeComponent();
        worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_Completed;
    }

    private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        if (outLine.Data != null)
        {
            if (!worker.IsBusy) //Check if Worker is working and avoid exception
               worker.RunWorkerAsync();     
        }
    }

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        //Process some Long-Running Task
        Thread.Sleep(5000)
        e.Result = "Done!";
    }

    private void worker_Completed(object sender, RunWorkerCompletedEventArgs e)
    {
       textbox.Text = e.Result.ToString();
    }
  }
}

此外,您可能对Task Library感兴趣,这使得线程的处理更容易。

更新:

你说:

  

我想实时更新我的​​文本框。

这将打印您的批处理文件直接在文本框中发送到Standardoutput的文本。所以我认为你不再需要了。

private void OutputHandler(object sendingProcess, DataReceivedEventArgs e)
    {
        if (!string.IsNullOrWhiteSpace(e.Data))
           BeginInvoke(new MethodInvoker(() => { textBox1.Text = e.Data; }));
    }

答案 1 :(得分:0)

感谢@Sebi,我设法解决了所有问题。事实证明,我不像有些人建议的那样需要BackgroundWorker。

查看最终代码,它就像魅力一样:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;


namespace CMD_testing
{
    public partial class Form1 : Form
    {
    public Form1()
    {
        InitializeComponent();
    }

    private void button2_Click(object sender, EventArgs e)
    {

        Process process;
        process = new Process();
        process.StartInfo.FileName = @"C:\\Project\Test\Other Data.bat";
        process.StartInfo.UseShellExecute = false;
          process.StartInfo.CreateNoWindow = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);

        process.StartInfo.RedirectStandardInput = true;
        process.Start();
        process.BeginOutputReadLine();
        process.Close();
    }

    private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        if (outLine.Data != null)
        {
            BeginInvoke(new MethodInvoker(() => { textBox1.AppendText(outLine.Data + Environment.NewLine); }));
        }

    }
  }

}