C#学习教程:C#-使用非主线程来更新GUI我想返回FTP应用程序生成的输出以显示在GUI文本框中。我尝试使用以下截断的代码。上传类(beginProcess()是一个用于启动线程的方法(此处未显示)):publicdelegatevoidWputOutputHandler(objectsender,DataReceivedEventArgse);上传类{私人WputOutputHandlerwputOutput;beginProcess(){Processpr=newProcess();pr.StartInfo.FileName=@"wput.exe";pr.StartInfo.RedirectStandardOutput=true;pr.StartInfo.UseShellExecute=false;pr.StartInfo.WindowStyle=ProcessWindowStyle.Hidden;pr.OutputDataReceived+=newDataReceivedEventHandler(OnDataReceived);pr.ErrorDataReceived+=newDataReceivedEventHandler(OnDataReceived);pr.Start();pr.BeginOutputReadLine();pr.WaitForExit();}publicvoidOnDataReceived(objectsender,DataReceivedEventArgse){if(wputOutput!=null){wputOutput(sender,e);}}公共事件WputOutputHandlerWputOutput{添加{wputOutput+=value;}移除{wputOutput-=值;}}}绑定类:publicvoidEventSubscriber(){uploadSession.WputOutput+=Main.writeToTextBoxEvent;}主类:publicvoidwriteToTextBoxEvent(objectsender,DataReceivedEventArgse){if(this.textBox1.InvokeRequired){MethodInvoker现在是什么?}else{textBox1.Text=e.Data;正如您看到的,当它进入Main方法的writeToTextBoxEvent时,我的想法用完了我不确定使用自定义事件进行UI更新是否是最好的方法。如果有人能指出我正确的方向,我将不胜感激。这个怎么样:publicvoidwriteToTextBoxEvent(objectsender,DataReceivedEventArgse){if(this.textBox1.InvokeRequired){//在.Net2.0中this.textBox1.BeginInvoke(newMethodInvoker(()=>writeToTextBoxEvent(sender,e)));//在.Net3.5中(上面也是可能的,但看起来更好)this.textBox1.BeginInvoke(newAction(()=>writeToTextBoxEvent(sender,e)));}else{textBox1.Text=e.Data;与Richard的解决方案相比,这种方法的优势在于您不需要将执行代码编写两次(在BeginInvoke()中和在else路径中)。更新如果您使用的是.Net3.5,请将其作为扩展方法:}else{动作();}}publicstaticvoidSafeBeginInvoke(thisControlcontrol,Actionaction){if(control.InvokeRequired){control.BeginInvoke(action);}else{动作();}}}并以这种方式使用它:publicvoidwriteToTextBoxEvent(objectsender,System.Diagnostics.DataReceivedEventArgse){//将它写成一行this.textBox1.SafeBeginInvoke(newAction(()=>textBox1.Text=e。数据));this.textBox1.SafeBeginInvoke(newAction(()=>{//写多行textBox1.Text=e.Data;}));}if(this.textBox1.InvokeRequired){Actiona=()=>{textBox1.文本=e.Data;};textBox1.Invoke(a);也就是使用Invoke方法使用delegate(它可以是一个用于捕获局部变量的闭包)。这将安排委托在文本框的线程上执行。当委托完成执行时,将返回Invoke。当您不需要等待时,还有一个异步版本(BeginInvoke)。编辑:忘记使用local因为InvokeacceptsDelegate类型推断失败。请注意,您当然可以更早地创建委托并在两个分支中使用它以避免重复代码。这是一个流行的扩展机制:;}else{动作();}}Usage:publicvoidwriteToTextBoxEvent(objectsender,DataReceivedEventArgse){this.textBox1.InvokeIfRequired(()=>{textBox1.Text=e.Data;}}如果你需要一个响应UI,你需要一个工作线程和一个主线程来更新UI。我认为您需要一个工作线程来查找正在接收的数据,然后使用工作线程中的委托将数据写入您的TextBox。类似于:publicdelegatevoidtextBoxWriteDelegate(stringmsg);privatevoidtextBoxWrite(stringsMess){textBox.AppendText(sMess);从你的工作线程:Invoke(newtextBoxWriteDelegate(textBoxWrite),newobject[]{"Launchingftpcmdline....n"});抱歉,这是net1.1;)有一种更好的方法来编写2.0及更高版本的委托......我为此创建了一个小帮手:classLayoutsEngine{internalstaticvoidThreadSafeDoer(FormForm,DelegateWhattodo){if(!Form.IsDisposed){如果(Form.InvokeRequired){Form.Invoke(Whattodo);}else{Whattodo.DynamicInvoke();我正在使用这个:LayoutsEngine.ThreadSafeDoer(this,newMethodInvoker(delegate(){txtWhatever.Text=whatever();//和任何其他GUI干预}));另外,如果有人有办法在这里减少MethodInvoker(),请发表评论。以上就是C#学习教程:C#-使用非主线程更新GUI共享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
