未验证 提交 2ac5e2bb 编写于 作者: D David Fowler 提交者: GitHub

Set the async local just before execution (#54133)

* Set the async local just before execution.
- Subscribing to DiagnosticListener.AllListeners replays all created DiagnosticListener instances. Because of this, we need to set the async local just before the execution of the entry point so that we only collect the events that are relevant to the call. Right now, it's also firing with the async local set pre-maturely.
- Wrote a concurrency test to make sure it's safe to instantiate the factory in parallel.
上级 49fa010d
......@@ -194,10 +194,6 @@ public HostingListener(string[] args, MethodInfo entryPoint, TimeSpan waitTimeou
public object CreateHost()
{
// Set the async local to the instance of the HostingListener so we can filter events that
// aren't scoped to this execution of the entry point.
_currentListener.Value = this;
using var subscription = DiagnosticListener.AllListeners.Subscribe(this);
// Kick off the entry point on a new thread so we don't block the current one
......@@ -208,6 +204,10 @@ public object CreateHost()
try
{
// Set the async local to the instance of the HostingListener so we can filter events that
// aren't scoped to this execution of the entry point.
_currentListener.Value = this;
var parameters = _entryPoint.GetParameters();
if (parameters.Length == 0)
{
......
......@@ -6,6 +6,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Extensions.Hosting.Tests
......@@ -250,5 +251,27 @@ public void TopLevelStatements()
Assert.NotNull(factory);
Assert.IsAssignableFrom<IServiceProvider>(factory(Array.Empty<string>()));
}
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NoSpecialEntryPointPattern.Program))]
public void NoSpecialEntryPointPatternCanRunInParallel()
{
var factory = HostFactoryResolver.ResolveServiceProviderFactory(typeof(NoSpecialEntryPointPattern.Program).Assembly, s_WaitTimeout);
Assert.NotNull(factory);
var tasks = new Task<IServiceProvider>[30];
int index = 0;
for (int i = 0; i < tasks.Length; i++)
{
tasks[index++] = Task.Run(() => factory(Array.Empty<string>()));
}
Task.WaitAll(tasks);
foreach (var t in tasks)
{
Assert.IsAssignableFrom<IServiceProvider>(t.Result);
}
}
}
}
......@@ -9,7 +9,7 @@ public class Program
{
public static void Main(string[] args)
{
Console.ReadLine();
System.Threading.Thread.Sleep(-1);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册