我需要一些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
}
}
}
答案 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); }));
}
}
}
}