未验证 提交 34eed9ce 编写于 作者: M Maryam Ariyan 提交者: GitHub

Fix some issues with background thread compilation (#42986)

- Resolve dependencies before counting to avoid the race
where its possible for the background thread to run before
the main thread resulting in singletons being resolved during
compilation (it's meant to be side effect free).

- We also avoid capturing the ExecutionContext on the background thread
to avoid capture of async locals.

Fixes dotnet/extensions#3566

Taken from https://github.com/dotnet/extensions/pull/3569/commits/07e4459b6e81d10c9b3a6561f4cc0fe5a6cbcf8b
上级 39e080d5
......@@ -47,6 +47,7 @@
<Reference Include="System.Reflection.Primitives" />
<Reference Include="System.Runtime" />
<Reference Include="System.Threading" />
<Reference Include="System.Threading.ThreadPool" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or
......
......@@ -20,12 +20,30 @@ public DynamicServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescri
int callCount = 0;
return scope =>
{
// Resolve the result before we increment the call count, this ensures that singletons
// won't cause any side effects during the compilation of the resolve function.
var result = RuntimeResolver.Resolve(callSite, scope);
if (Interlocked.Increment(ref callCount) == 2)
{
Task.Run(() => base.RealizeService(callSite));
// Don't capture the ExecutionContext when forking to build the compiled version of the
// resolve function
ThreadPool.UnsafeQueueUserWorkItem(state =>
{
try
{
base.RealizeService(callSite);
}
catch
{
// Swallow the exception, we should log this via the event source in a non-patched release
}
},
null);
}
return RuntimeResolver.Resolve(callSite, scope);
return result;
};
}
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册