Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/Core/tests/UnitTests/Dispatching/DispatcherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,22 @@ public Task BackgroundThreadDoesNotGetDispatcherFromMainThread() =>

await Task.Run(() =>
{
DispatcherProviderStubOptions.SkipDispatcherCreation = true;

var dispatcher = Dispatcher.GetForCurrentThread();
Assert.Null(dispatcher);
// SkipDispatcherCreation is [ThreadStatic] and this delegate runs on a pooled
// thread. Reset it in a finally so the thread is returned to the pool clean.
// Otherwise the leaked flag makes Dispatcher.GetForCurrentThread() return null
// for a later test whose async continuation happens to resume on this same
// pooled thread, producing an intermittent NullReferenceException.
try
{
DispatcherProviderStubOptions.SkipDispatcherCreation = true;

var dispatcher = Dispatcher.GetForCurrentThread();
Comment on lines +68 to +72
Assert.Null(dispatcher);
}
finally
{
DispatcherProviderStubOptions.SkipDispatcherCreation = false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 AI-Generated Review (multi-model)

[major] Logic and Correctness — Resetting only the [ThreadStatic] flag does not undo the DispatcherProviderStub value created while skip mode was enabled. DispatcherProviderStub stores GetForCurrentThread() in a ThreadLocal<IDispatcher?>; when line 72 runs with SkipDispatcherCreation = true, that ThreadLocal caches null for this provider/thread, so a later Dispatcher.GetForCurrentThread() on the same pooled thread can still return the cached null after this finally block. Please avoid caching null in the provider when skip mode is active (or otherwise clear the per-thread cached value) so the dispatcher state is actually restored.

}
});
});

Expand Down
Loading