.NET4.0TPL不会让APM、EAP和BackgroundWorker异步模式过时吗?我有2种C#WPF应用程序项目:所有这些都应该产生2-10个长时间运行(天)的进程,用户可以取消和重新启动这些进程。我有兴趣遵循最佳设计实践。首先,现在,我有兴趣消除BackgroundWorker用法的歧义,但我希望我的问题对其他异步模式也有效。我在异步模式中看到了关于并发的(矛盾的)观点:“基于异步方法的异步编程方法几乎在所有情况下都优于现有方法。特别是对于IO绑定操作,此方法优于BackgroundWorker,因为代码更简单,你不需要防范竞争条件,结合Task.Run,??异步编程在CPU-bound操作方面优于BackgroundWorker,因为异步编程将运行代码的协调细节与Task.Run中转的工作分开到线程池”我仍然有问题:这些模式(BGW优先)在.NET4.5中是否已过时?如果它们在.NET4.5中已经过时,为什么它们在.NET4.0中没有过时?2A)我是否理解新的.NET4.0功能仍然“容易”在.NET4.0中实现/重现?我通常建议将.NET4.5与Task和/或await一起使用。但是Task和BGW有两种截然不同的场景。任务适用于可以链接到延续的一般较短的异步任务,等待适用于隐式编组回UI线程的任务。BGW在不影响UI响应能力的情况下适用于单个长时间操作。您可以将BGW拖放到设计图面上,然后双击以创建事件处理程序。如果您不想编组到另一个线程,则不必处理LongRunning或ConfigureAwait。许多人发现BGW比IProgress更容易进步。以下是在“冗长操作”场景中使用这两种方法的一些示例:由于问题特别提到了.NET4.0,因此这里是使用Task执行冗长操作同时向UI提供进度的简单代码:startButton.Enabled=false;vartask=Task.Factory.StartNew(()=>{foreach(varxinEnumerable.Range(1,10)){varprogress=x*10;Thread.Sleep(500);//假工作BeginInvoke((行动)委托{progressBar1.Value=progress;});}},TaskCreationOptions.LongRunning).ContinueWith(t=>{startButton.Enabled=true;progressBar1.Value=0;});BackgroundWorker的类似代码可能是:startButton.Enabled=false;BackgroundWorkerbgw=newBackgroundWorker{WorkerReportsProgress=true};bgw.ProgressChanged+=(sender,args)=>{progressBar1.Value=args.ProgressPercentage;};bgw.RunWorkerCompleted+=(sender,args)=>{startButton.Enabled=true;progressBar1.Value=0;};bgw.DoWork+=(sender,args)=>{foreach(varxinEnumerable.Range(1,10)){Thread.Sleep(500);((BackgroundWorker)sender).ReportProgress(x*10);}};bgw.RunWorkerAsync();现在,如果您使用的是.NET4.5,您可以使用Progress而不是使用Task的BeginInvoke调用从4.5开始,使用await可能更具可读性:startButton.Enabled=false;varpr=newProgress();pr.ProgressChanged+=(o,i)=>progressBar1。价值=我;awaitTask.Factory.StartNew(()=>{foreach(varxinEnumerable.Range(1,10)){Thread.Sleep(500);//假工作((IProgress)pr).Report(x*10);}},TaskCreationOptions.LongRunning);startButton.Enabled=true;progressBar1.Value=0;使用Progress意味着代码不耦合到特定的UI框架(即对BeginInvoke的调用),这与BackgroundWorker促进与特定UI框架解耦的方式非常相似。如果您不在乎,那么您无需介绍使用Progress所增加的复杂性。至于LongRunning,正如StephenToub所说:“你通常只使用LongRunning,如果你通过性能测试发现不使用它会导致其他工作处理长时间延迟”所以,如果你发现你需要使用它,那么你使用它-添加的分析或只是总是添加LongRunning参数的“复杂性”。不使用LongRunning意味着用于长时间运行操作的线程池线程将不可用于其他更短暂的任务,并且可能会强制线程池在启动另一个线程时延迟启动其中一个临时任务(至少一秒钟)。框架中没有属性明确指示BGW(或EAP或APM)已弃用。因此,由您决定这些东西何时何地“过时”。特别是BGW总是有一个非常具体的使用场景仍然适用于它。您在.NET4.0和4.5中有很好的选择;但我真的不认为BGW是“过时的”。我并不是说总是使用BackgroundWorker,我只是说在您自动弃用BackgroundWorker之前请三思,在某些情况下它可能是更好的选择。我认为这些模式(尤其是APM、EAP和BGW)在.NET4.5中已经过时了。async和Task.Run的结合在各个方面都优于BGW。事实上,我刚刚在我的博客上开始了一个系列,我将在其中将BGW与Task.Run进行比较,并展示它在各种情况下的繁琐程度;在某些情况下,它只是稍微麻烦一些,但在其他情况下,它更麻烦。现在,它们在.NET4.0中是否过时完全是另一个问题。在您的另一篇文章中,您谈到了使用VS2010开发.NET4.0,因此向后移植Microsoft.Bcl.Async不是一个选项。在这种情况下,APM和EAP都不能被视为过时的IMO。在这个平台上,您可以将Task.Factory.StartNew视为BGW的替代品,但BGW在进度报告以及进度和完成事件的自动线程编组方面确实具有一些优势。更新:我最近更新了我的一篇旧博客文章,其中讨论了后台操作的各种实现。在Task.Run文章中,当我谈到“任务(异步方法)”时,我的意思是使用具有所有.NET4.5异步支持的Task、Task.Run等。“任务(任务并行库)”部分正在评估.NET4.0中存在的任务。我的问题是:.NET4.0TPL不会使APM、EAP和BackgroundWorker异步模式过时吗?即有疑问,要求确认或否。如果.NET4.5中的某些内容已过时,那么我不明白它在.NET4.0中的不同之处,即使用TaskParallel库(不涉及async/await和.NET4.5专有支持)我很高兴在NickPolyak的代码项目文章“TaskParallelLibraryandAsync-Awaitfunction-UsagePatternsinaSimpleSample”中找到NickPolyak的答案:仍然愿意看到上述C#学习教程的任何不同论点:Doesn't.NET4.0TPLmakeAPM、EAP和BackgroundWorker异步模式过时了?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
