C#使用backgroundworker进程更新和追加文本框值我有一个c#windowsformapp我拼凑起来的。很简单:输入:应用程序在源文件夹中的文本文件中搜索输入的文本字符串;如果找到该字符串,它将将该文件和同名的图像文件复制到目标文件夹。它根据整数输入多次执行此操作。所以我有一个按钮,在按钮单击事件上我调用ProcessImages(tbDID.Text,tbSource.Text,tbDest.Text,comboBoxNumberImages.SelectedItem.ToString());这是:privatevoidProcessImages(stringDID,stringSourceFolder,stringDestFolder,stringstrNumImages){intImageCounter=0;intMaxImages=Convert.ToInt32(strNumImages);DirectoryInfodi=newDirectoryInfo(SourceFolder);foreach(FileInfofiindi.GetFiles("*.txt")){if(fi.OpenText().ReadToEnd().Contains(DID)){//找到一个!FileInfofi2=newFileInfo(fi.FullName.Replace(".txt",".tif"));if(fi2.Exists){try{tbOutput.Text+="复制"+fi2.FullName+"到"+tbDest.Text+"rn";fi2.CopyTo(tbDest.Text+@""+fi2.Name,true);tbOutput.Text+="复制"+fi.FullName+"到"+tbDest.Text+"rn";fi.CopyTo(tbDest.Text+@""+fi.Name,true);图片计数器++;}catch(Exceptionex){MessageBox.Show(ex.Message);}}}如果(ImageCounter>=MaxImages)中断;发生的事情是该过程运行良好,但我希望在复制文件时更新表单上的文本框。基本上,表单在运行时是空白的,完成后在文本框中输出。我想实现一个BackgroundWorker让它在运行时更新UI。我看过这些例子,但我并没有真正理解它们。我没有完成百分比值,我只想在每次迭代时更新.Text更改并显示它。我什至不认为我必须将实际的复制操作放在不同的线程中,听起来它需要与主UI线程分开运行。也许我完全把这个复杂化了……有人能把我推向正确的方向吗?谢谢!如果您使用后台工作者,则可以使用ReportProgress方法返回任何整数,例如已处理的记录数。它不一定是百分比。然后,在ProgressChanged处理程序中,您可以更新文本框。例如intcount=e.ProgressPercentage;textBox1.Text=string.Format("已处理{0}张图片。",count);如果您不想使用后台工作者,您可以在循环中调用Application.DoEvents()。这将使UI有机会刷新自身并响应用户操作。但要小心——它会减慢你的程序,所以你可能只想每100次迭代调用一次。您与后台工作人员走在正确的轨道上。这是我放在一起向您展示如何执行此操作的示例。使用Form1创建一个新的Windows应用程序。添加4个控件:label1、backgroundWorker1、button1和button2。然后使用此代码隐藏。然后,您可以使用ReportProgressuserState向主线程报告您想要的任何内容。在这个例子中,我传递了一个字符串。ProgressChanged事件处理程序然后位于UI线程上并更新文本框。publicpartialclassForm1:Form{intbackgroundInt;publicForm1(){InitializeComponent();backgroundWorker1.WorkerReportsProgress=true;}privatevoidbackgroundWorker1_ProgressChanged(objectsender,ProgressChangedEventArgse){label1.Text=e.UserState}voprivate;backgroundWorker1_DoWork(objectsender,DoWorkEventArgse){backgroundInt=1;while(backgroundWorker1.CancellationPending==false){System.Threading.Thread.Sleep(500);backgroundWorker1.ReportProgress(0,String.Format("我找到了文件#{0}!",backgroundInt));背景诠释++;}}privatevoidbutton1_Click(objectsender,EventArgse){backgroundWorker1.RunWorkerAsync();}privatevoidbutton2_Click(objectsender,EventArgse){backgroundWorker1.CancelAsync();用户界面不会更新,因为您不允许在长时间运行的文件处理循环中处理任何窗口消息。WinForms应用程序重新绘制以响应在主线程的消息队列中处理的WM_PAINT消息。最简单的解决方案是强制UI更新:在循环内修改文本框后尝试在表单上调用Update()。您的应用程序仍会被UI冻结(对鼠标点击无响应等),但至少应在屏幕上绘制进度消息。如果您真的需要更新显示器,请到此为止。下一级解决方案是允许您的应用程序在文件处理循环中处理挂起的窗口消息。在循环中调用Application.DoEvents()(而不是form.Update)。这将允许表单在文本输出更新时重新绘制,并将消除您的UI冻结-应用程序可以响应鼠标和键盘活动。但是请注意,当当前活动正在进行时,用户可以单击启动当前活动的按钮——重新进入。您至少应该禁用启动长时间运行的文件处理的菜单或按钮,以防止重新进入。第三级解决方案是使用后台线程进行文件处理。这引入了一组您需要注意的新问题,并且在许多情况下会导致线程过度。如果您不允许用户在处理文件时对您的应用程序执行任何其他操作,则将文件处理推送到后台线程没有多大意义。只需创建一个(1)委托来包装您的ProcessImages方法调用,(2)使用委托来触发调用,以及(3)当您想从ProcessImages方法更新文本框时,检查交叉操作并确保您refrom主线程更新:以上是C#学习教程:C#使用backgroundworker进程更新附加文本框值共享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——delegatevoidProcessImagesDelegate(stringdid,stringsourceFolder,stringdestFolder,stringstrNumImages);privatevoidProcessImages(stringDID,stringSourceFolder,stringDestFolder,stringstrNumImages){//做工作//更新表单中的文本框if(this.textBox1.InvokeRequired){this.textBox1.Invoke(newMethodInvoker(delegate(){this.textBox1.Text="委托更新";}));}else{this.textBox1.Text="定期更新";}//做更多的工作}publicvoidMyMethod(){newProcessImagesDelegate(ProcessImages).BeginInvoke(tbDID.Text,tbSource.Text,tbDest.Text,comboBoxNumberImages.SelectedItem.ToString(),null,null);如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
