C#异步等待使用LINQForEach()internalstaticasyncTaskAddReferencseData(ConfigurationDbContextcontext){foreach(varsinkNameinRequiredSinkTypeList){varsinkType=newSinkType(){Name=sinkName};context.SinkTypeCollection.Add(sinkType);awaitcontext.SaveChangesAsync().ConfigureAwait(false);如果我不想使用foreach(),而是想使用LINQForEach(),那么等效的写法是什么?例如,这个给出了编译错误。内部静态异步任务AddReferenceData(ConfigurationDbContextcontext){RequiredSinkTypeList.ForEach(sinkName=>{varsinkType=newSinkType(){Name=sinkName};context.SinkTypeCollection.Add(sinkType);awaitcontext.SaveChangesAsync().ConfigureAwait(false);});我得到的唯一没有编译错误的代码是这样的。internalstaticvoidAddReferenceData(ConfigurationDbContextcontext){RequiredSinkTypeList.ForEach(asyncsinkName=>{varsinkType=newSinkType(){Name=sinkName};context.SinkTypeCollection.Add(sinkType);awaitcontext.SaveChangesAsync().ConfigureAwait(false);});我担心这个方法没有异步签名,只有文字。这是我上面的第一段代码的正确等价物吗?不,这不对。这个ForEach不支持async-await并且要求你的lambda是asyncvoid,它只能在事件处理程序中使用。使用它将同时运行所有异步操作,而无需等待它们完成。您可以像普通的foreach一样使用它,但如果您想要扩展方法,则需要一个特殊的异步版本。您可以自己创建一个迭代项,执行异步操作并等待它:publicasyncTaskForEachAsync(thisIEnumerableenumerable,Funcaction){}}用法:内部静态异步任务AddReferencseData(ConfigurationDbContextcontext){awaitRequiredSinkTypeList.ForEachAsync(asyncsinkName=>{varsinkType=newSinkType(){Name=sinkName};context.SinkTypeCollection.Add(sinkType);awaitcontext.SaveChangesAsync().ConfigureAwait(false);});ForEachAsync的另一种(通常更有效)实现是启动所有异步操作,然后才一起等待它们,但这只有在您的操作可以并发运行时才有可能(但并非总是如此)(例如,实体框架):publicTaskForEachAsync(thisIEnumerableenumerable,Funcaction){returnTask.WhenAll(enumerable.Select(item=>action(item)));正如评论中所指出的,您可能不希望在foreach中使用SaveChangesAsync。准备更改然后一次保存所有更改可能更有效。要在方法中编写await,您的方法需要标记为异步。当你写ForEach方法的时候,你把wait写在一个labda表达式里,这和你从方法中调用的方法是完全不同的。您需要将此lamdba表达式移动到一个方法并将该方法标记为异步,因为@i3arnon表示您需要将ForEach方法标记为异步,.NetFramework尚未提供。所以需要自己写。foreach的初始示例在每次循环迭代后有效地等待。最后一个示例调用List.ForEach(),它采用Action含义,即异步lambda将编译为void委托,而不是标准任务。事实上,ForEach()方法会一次次地调用“迭代”,而不用等待每次迭代完成。这也会传播到您的方法,这意味着AddReferenceData()可能会在工作完成之前完成。所以不,这不是等价的,行为是完全不同的。事实上,假设它是一个EF上下文,它会爆炸,因为它可能不会同时跨多个线程使用。另请阅读Deepu提到的http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx,了解为什么坚持使用foreach可能会更好。为什么不使用AddRange()方法?context.SinkTypeCollection.AddRange(RequiredSinkTypeList.Select(sinkName=>newSinkType(){Name=sinkName});awaitcontext.SaveChangesAsync().ConfigureAwait(false);感谢大家的反馈。在循环,我相信以下两种方法现在是等效的,一种使用foreach(),另一种使用.ForEach()。但是,正如Deepu提到的,我将阅读Eric的关于为什么foreach可能更好的帖子。以上就是C#学习教程:C#异步等待使用LINQForEach()全部内容分享。如果对大家有用,需要详细了解C#学习教程,希望大家多加关注—publicstaticasyncTaskAddReferencseData(ConfigurationDbContextcontext){RequiredSinkTypeList.ForEach(sinkName=>{varsinkType=newSinkType(){Name=sinkName};context.SinkTypeCollection.Add(sinkType);});等待context.SaveChangesAsync().ConfigureAwait(false);}publicstaticasyncTaskAddReferenceData(ConfigurationDbContextcontext){foreach(varsinkNameinRequiredSinkTypeList){varsinkType=newSinkType(){Name=sinkName};context.SinkTypeCollection.Add(sinkType);}awaitcontext.SaveChangesAsync().ConfigureAwait(false);}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
