Jod*_*ell 5 c# async-await asp.net-core
我已经将Microsoft.VisualStudio.Threading导入.Net Core Web App。我专门这样做是为了利用AsyncLazy<T>
。
我想确保自己做对了,所以我导入了适当的分析器。
警告和文档明确指出JoinableTaskFactory
应将a 注入到我的实现中。
我的问题是,如何JoinableTaskFactory
在.Net Core Web App的配置中实例化它?
简单吗
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddSingleton(new JoinableTaskFactory());
// ...
}
Run Code Online (Sandbox Code Playgroud)
还是,这都是错误的吗?
是的,您可以Microsoft.VisualStudio.Threading
在 ASP.NET Core 应用程序中使用该库。但是虽然JoinableTaskFactory
在这样的应用程序中“工作”,但这是一个很好的迹象,你做错了什么。
该分析仪总是合适的,当然,并警告你看到的是也许是指出你不应该叫Task.Result
,Task.Wait()
等,这些同步块线程,可严重降低你的web应用程序的可扩展性(或与此有关的任何应用程序)。您应该尽可能使用await代替。
JoinableTaskFactory
当您无法使用await但您仍然需要调用异步代码时,是否可以介入。UsingJTF.Run
仍然会阻塞调用线程,但它会以一种避免死锁的方式SynchronizationContext
在应用程序中有单线程时这样做。我不认为ASP.NET Core 有这样的东西,所以这不是问题。JTF.Run
仍然比Task.Wait
因为它可以将原始线程重用于延续而不是第二个线程更有效。
如果您确实选择在 Web 应用程序中使用 JTF,并且 ASP.NET Core 不使用单线程,SynchronizationContext
那么您可以创建单个 JTF 实例并将其与整个应用程序共享。但是,如果它确实有一个单线程SynchronizationContext
,那么每个 Web 请求将是一个,这意味着您需要JoinableTaskContext
为每个请求创建一个新的,因为它们关联到一个SynchronizationContext
。您总是从JoinableTaskContext
实例中获取 JTF实例。
ThreadHelper.JoinableTaskFactory 属性仅适用于在 VS 进程中运行的代码。如果您的代码在 proc 之外运行(例如在 vstest.executionengine.exe 运行程序中),它将无法工作。
因此,正如包的名称Microsoft.VisualStudio.Threading
所示,它旨在用于 Visual Studio 扩展。您为其 AsyncLazy 实现链接的代码使用 JoinableTaskFactory,因此它可能不适合 Visual Studio 之外的环境。我当然不会在需要切换到 UI 线程的 VS 扩展之外使用它。
Steven Cleary 的 AsyncEx 库有一个AsyncLazy,并且wiki 页面链接到这篇标题为 AsyncLazy 的 Steven Toub 博客文章。该博客文章指出,惰性语义并没有真正比所Task<T>
提供的内容添加太多内容,尽管由于值工厂在到达等待之前可能会做很多工作,因此他的示例在线程池上运行它并解开Task<Task<T>>
.
编辑:正如评论中所指出的,我从文档中引用的内容有些断章取义。然而,vs-threading 库是为了避免在同步上下文(主要是 GUI)中使用 async 时出现死锁。问题的作者正在使用的 ASP.NET Core 没有同步上下文,因此不需要专门担心主线程的死锁。虽然使用 vs-threading 库可能不会引起问题,正如我的引文所说,但我仍然认为它不适合没有同步上下文的任何东西,并且有更好的替代方案,例如Task<T>
直接使用而不需要任何 AsyncLazy执行。
归档时间: |
|
查看次数: |
166 次 |
最近记录: |