当前位置: 首页 > 编程语言 > C#

后台工作者:在执行RunWorkerCompleted之前确保ProgressChanged方法已经完成分享

时间:2023-04-10 20:26:52 C#

后台工作者:在执行RunWorkerCompleted之前确保ProgressChanged方法已经完成假设我正在使用后台工作者并且我有以下方法:privatevoidbw_DoWork(objectsender,DoWorkEventArgse){finalData=MyWork(senderasBackgroundWorker,e);}privatevoidbw_ProgressChanged(objectsender,ProgressChangedEventArgse){inti=e.ProgressPercentage;//MissedforiDebug.Print("BWProgressChangedBegin,i:"+i+",ThreadId:"+Thread.CurrentThread.ManagedThreadId);//我用它来更新表格和XY-Plot,以便用户可以看到进度。UpdateGUI(e.UserStateasMyData);Debug.Print("BWProgressChangedEnd,i:"+i+",ThreadId:"+Thread.CurrentThread.ManagedThreadId);}privatevoidbw_RunWorkerCompleted(objectsender,RunWorkerCompletedEventArgse){if((e.Cancelled==true)){//取消}elseif(!(e.Error==null)){MessageBox.Show(e.Error.信息);}else{Debug.Print("BWRunWorkerCompletedBegin,ThreadId:"+Thread.CurrentThread.ManagedThreadId);//我用它来更新表格和XY-Plot,//以便用户可以看到最终数据。UpdateGUI(finalData);Debug.Print("BWRunWorkerCompletedEnd,ThreadId:"+Thread.CurrentThread.ManagedThreadId);}}现在我假设bw_RunWorkerCompleted方法在调用bw_RunWorkerCompleted方法之前完成但它没有,我不明白为什么?我得到以下输出:Worker,i:0,ThreadId:27BWProgressChangedBegin,i:0,ThreadId:8BWProgressChangedEnd,i:0,ThreadId:8Worker,i:1,ThreadId:27BWProgress更改开始,i:1,ThreadId:8BW进度更改结束,i:1,ThreadId:8Worker,i:2,ThreadId:27BW进度更改开始,i:2,ThreadId:8BW运行Worker完成开始,ThreadId:8BWRunWorkerCompletedEnd,ThreadId:8mscorlib.dll中发生类型为“System.InvalidOperationException”的第一次机会异常错误<--集合已修改;枚举操作可能无法执行。错误<--NationalInstruments.UI.WindowsForms。Graph.ClearData()MagagedID8是MainThread,27是WorkerThread。我可以在Debug/Windows/Threads中看到这一点。如果我不在bw_ProgressChanged方法中调用UpdateGUIint,则不会发生错误。但是随后用户在表格和XY图中看不到任何进展。将MyWork方法编辑为如下所示:publicMyData[]MyWork(BackgroundWorkerworker,DoWorkEventArgse){MyData[]d=newMyData[n];对于(inti=0;i“Windows”>“线程”调试窗口来验证它是否在主线程上运行。使用Debug.Print显示Thread.CurrentThread.ManagedId的值可以帮助确保所有调用都在UI线程上运行。您可以通过确保在主线程上执行RunWorkerAsync()调用来修复它。然后是重新进入错误的陷阱,当ProgressChanged执行某些操作使UI调度程序再次运行时,就会发生这种情况。往往与线程竞争一样难以调试。这可能发生的三种基本方式:通过在RunWorkerCompleted事件上设置断点来诊断重入错误。您应该看到ProgressChanged事件处理程序返回,深藏在调用堆栈中。以及导致重新进入的声明。如果跟踪对您没有帮助,请将其张贴在您的问题中。最大的缺陷是你下面的假设是错误的。现在我假设bw_ProgressChanged方法在调用bw_RunWorkerCompleted方法之前已经完成。但它没有,我不明白为什么?不要沉迷于在心理上序列化逻辑流。使用WinForms/WPF,您会发生两个完全独立的异步事件。您让BGW向UI发送请求(通过worker.ReportProgress)以执行进度更新。UI线程必须接收请求并在bw_ProgressChanged事件运行时安排它。终止独立于BGW(通过myWork)决定,可能是通过完全完成作业,或者因为抛出未捕获的异常,或者最终用户可能希望取消给定实例的工作。然后它向UI线程发送请求以运行bw_RunWorkerCompleted方法。UI必须在许多待办事项列表上再次安排它。以上就是C#学习教程:后台工作程序:确保ProgressChanged方法共享的所有内容都已经完成,然后再执行RunWorkerCompleted。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——本文来自网络收集,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处: