C# - 使用非主线程更新界面 [英] C# - Updating GUI using non-main Thread
问题描述
我有一个具有类
- 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屋!