Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 未通过BackgroundWorker在启用DataReceiveDevenHandler的情况下实时更新文本框_C#_Multithreading_Backgroundworker - Fatal编程技术网

C# 未通过BackgroundWorker在启用DataReceiveDevenHandler的情况下实时更新文本框

C# 未通过BackgroundWorker在启用DataReceiveDevenHandler的情况下实时更新文本框,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,我需要一些后台工作人员的帮助。使用Visual Studio 2015及其windows窗体 我是这类事情的新手,真的不知道它是如何工作的等等。到目前为止,我的代码是基于这里的各种帖子 工人没有被解雇,但不知道为什么。我相信这与datarcievedeventhandler有关,因为当我移动时,如果我移动worker.DoWork+=worker\u DoWork\uux;和worker.RunWorkerAsync();在点击按钮的事件中,禁用DataReceivedEventHandler,

我需要一些后台工作人员的帮助。使用Visual Studio 2015及其windows窗体

我是这类事情的新手,真的不知道它是如何工作的等等。到目前为止,我的代码是基于这里的各种帖子

工人没有被解雇,但不知道为什么。我相信这与datarcievedeventhandler有关,因为当我移动时,如果我移动worker.DoWork+=worker\u DoWork\uux;和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

    }

}

}

问题在于您概述了
RunWorkerAsync()。此方法触发处理异步代码的DoWork事件。通过DoWork的EventArgs,您可以将结果重用回主线程,并将其打印到文本框中。您可以在RunWorkerCompleted事件中获得结果。下面是一个基于您的代码的小示例:

  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();
    }
  }
}
此外,您可能会对哪种方法更容易处理线程感兴趣

更新:

你说:

我想实时更新我的文本框

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

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

多亏了@Sebi,我成功地解决了所有问题。事实证明,我不需要像一些人所建议的那样有一个后台工作人员

请参见最终代码,其工作原理类似于符咒:

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

    }
  }

}

为什么要对//worker.RunWorkerAsync();?进行注释;???因为我得到一个异常错误,说Backgroundworker已经在运行,不能同时运行。因此,我认为DataReceivedHandler踢了其中一个,但我可能错了,您需要取消注释该行。如果您尝试再次运行它,它就会崩溃。因此,首先,检查(!worker.IsBusy){worker.RunWorkerAsync();}-这将只允许它在当前未运行时运行。酷工作了。然而。我的文本框仅在CMD完成运行后更新。我需要实时更新它。此外,似乎每次从CMD接收数据时,该方法只调用一次。谢谢,但我的文本框没有实时更新,即每次将一行插入CMD窗口时。它只输出“完成!”。知道为什么吗?@TomPisz我不清楚你的目标。如果调用worker.RunWorkerAsync();这将恰好运行一次您的嫁妆活动。因此,可以肯定的是,它的结果是一次成功!在我的例子中。请注意,Backgroundworker并不意味着实时做某事。它只是让你在长时间运行的操作上有一个响应用户界面的能力。对不起,Sebi,但这是我在各种网站和论坛上找到的。我需要实时更新文本框,有人建议使用backgrounder。我对C#和这类事件不太熟悉,所以不太确定如何做,只是尝试和错误的方法。“你能给我指出正确的方向吗?”汤姆皮兹我更新了我的答案。我不确定你是否理解正确。谢谢。你完全理解我。CMD输出需要实时重定向到文本框。有了你们更新的答案,我得到了跨线程异常错误,我想这是我使用backgrounder的原因。希望这是有意义的。