懒惰共享异步资源-澄清?我在斯蒂芬的书的最后看到了这个例子。这段代码可以被多个线程访问。静态int_simpleValue;staticreadonlyLazyMySharedAsyncInteger=newLazy(async()=>{awaitTask.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);return_simpleValue++;});异步任务GetSharedIntegerAsync(){intsharedValue=awaitMySharedAsyncInteger.Value;}无论多少部分代码同时调用Value,Task只创建一次,返回给所有调用者。但随后他说:如果有不同的线程类型可以调用Value(例如,UI线程和线程池线程,或者两个不同的ASP.NET请求线程),最好始终在线程池线程不错。所以他建议使用下面的代码让整个代码运行在一个线程池线程中:.Delay(TimeSpan.FromSeconds(2));返回_simpleValue++;;}));问题:我不明白第一个代码有什么问题。延续将在线程池线程中执行(由于ConfigureAwait,我们不需要原始上下文)。此外,一旦来自任何线程的任何控制到达等待,控制将返回给调用者。我没有看到第二个代码试图解决的额外风险。我的意思是-第一个代码中“可能调用Value不同的线程类型”有什么问题?第一个代码中“可能调用Value的不同线程类型”有什么问题?这段代码没有错。但是假设您有一些CPU绑定工作以及异步初始化调用。想象一下这个例子:staticreadonlyLazy>MySharedAsyncInteger=newLazy>(async()=>{inti=0;while(i现在,你没有针对这种行为的“保护”。我假设Stephan提到了UI线程,因为你不应该做任何超过50毫秒的事情。你不希望你的UI线程冻结。当你使用Task.Run调用委托时,你可以从可能传递长寿命的地方覆盖自己委托给Lazy。由StephanToub在AsyncLazy中讨论解决问题:这里我们有一个新的AsyncLazy,它派生自Lazy>并提供两个构造函数。每个构造函数从调用者那里获取一个函数,就像Lazy一样。事实上,第一个构造函数接受与Lazy相同的Func。但是,我们没有将Func直接传递给基本构造函数,而是传递了一个新的Func>,它仅使用StartNew来运行用户提供的Func。第二个构造函数更花哨。不是采用Func,而是usingFunc>.有了这个函数,我们有两个很好的选择来处理它。第一种是简单地将函数直接传递给基础构造函数,例如:publicAsyncLazy(Func>taskFactory):base(taskFactory){}这个选项有效,但这意味着当用户访问这个实例的Value属性时,taskFactory委托将被同步调用。如果taskFactory委托在返回任务实例之前只做很少的工作,这可能是完全合理的。但是,如果taskFactory委托执行任何不可忽略的工作,则对Value的调用将阻塞,直到对taskFactory的调用完成。为了涵盖这种情况,第二种方法是使用Task.Factory.StartNew运行任务。Factory.StartNew,它异步运行委托本身,就像第一个构造函数一样,即使这个委托返回了一个任务。以上就是C#学习教程:异步资源的懒共享——澄清?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: