C# - 使用非主线程更新界面 [英] C# - Updating GUI using non-main Thread

查看:251
本文介绍了C# - 使用非主线程更新界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有类


  • GUI

  • 上传
  • $程序b $ b
  • 和2类之间的缓冲器 - 即所使用的2类之间的通信。

  • GUI
  • Upload
  • and a buffer between the 2 classes - ie used to communicate between the 2 classes .

上传类使用过程来运行一个FTP命令行应用程序。我想回到什么,在文本在GUI中显示的FTP应用程序生成的输出。结果
我已经尝试使用下面的代码有被截断。

The Upload class uses Process to run an command line FTP app. I want to return what output produced by the FTP app to be displayed in a textbox in the GUI.
I have tried using the following code that has been truncated.

上传类(beginProcess()是用于启动线程(此处未示出)的方法):

Upload Class (beginProcess() is a method used to start the Thread (not shown here)):

public delegate void WputOutputHandler(object sender, DataReceivedEventArgs e);
class Upload
{
    private WputOutputHandler wputOutput;

    beginProcess()
    {
        Process pr = new Process();                                                 
        pr.StartInfo.FileName = @"wput.exe";                                        
        pr.StartInfo.RedirectStandardOutput = true;
        pr.StartInfo.UseShellExecute = false;
        pr.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        pr.OutputDataReceived += new DataReceivedEventHandler(OnDataReceived);
        pr.ErrorDataReceived += new DataReceivedEventHandler(OnDataReceived);
        pr.Start();                                                                 
        pr.BeginOutputReadLine();
        pr.WaitForExit();
    }


    public void OnDataReceived(object sender, DataReceivedEventArgs e)
    {
        if(wputOutput != null)
        {
            wputOutput(sender, e);
        }
    }


    public event WputOutputHandler WputOutput
    {
        add
        {
            wputOutput += value;
        }
        remove
        {
            wputOutput -= value;
        }
    }
}



Buffer类:

Buffer Class:

public void EventSubscriber()
{
    uploadSession.WputOutput += Main.writeToTextBoxEvent;
}



主类:

Main Class:

public void writeToTextBoxEvent(object sender, DataReceivedEventArgs e)
{
    if(this.textBox1.InvokeRequired)
    {
        MethodInvoker what now?
    }
    else
    {
        textBox1.Text = e.Data;
    }
}



正如你所看到的,当它来到主方法的writeToTextBoxEvent,我已经跑出去的想法。我不知道这样做是否使用自定义事件的UI更新,甚至做到这一点的最好办法。如果有人可以点我在正确的方向,我将不胜感激。

As you can see, when it come to the Main method's writeToTextBoxEvent, I've ran out of ideas. I'm not sure whether doing a UI update using a custom event is even the best way to do it. If someone could point me in the right direction I would be most grateful.

推荐答案

这个怎么样:

public void writeToTextBoxEvent(object sender, DataReceivedEventArgs e)
{
    if(this.textBox1.InvokeRequired)
    {
        // In .Net 2.0
        this.textBox1.BeginInvoke(new MethodInvoker(() => writeToTextBoxEvent(sender, e)));

        // In .Net 3.5 (above is also possible, but looks nicer)
        this.textBox1.BeginInvoke(new Action(() => writeToTextBoxEvent(sender, e)));
    }
    else
    {
        textBox1.Text = e.Data;
    }
}

有关对理查德的解决了这个方法的优点是你不'T需要编写代码执行两次(在的BeginInvoke(),再次在其他路径)。

The advantage for this method against Richard solution is you don't need to write the executing code twice (within the BeginInvoke() and again in the else path).

如果你对净3.5使它作为扩展方式:

If you're on .Net 3.5 make it as an extension method:

public static class ControlExtensions
{
    public static void SafeInvoke(this Control control, Action action)
    {
        if (control.InvokeRequired)
        {
            control.Invoke(action);
        }
        else
        {
            action();
        }
    }

    public static void SafeBeginInvoke(this Control control, Action action)
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(action);
        }
        else
        {
            action();
        }
    }
}

和使用它的方法:

public void writeToTextBoxEvent(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    // Write it as a single line
    this.textBox1.SafeBeginInvoke(new Action(() => textBox1.Text = e.Data));

    this.textBox1.SafeBeginInvoke(new Action(() =>
        {
            //Write it with multiple lines
            textBox1.Text = e.Data;
        }));
}

这篇关于C# - 使用非主线程更新界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆