Skip to content

Commit c4b34f3

Browse files
authored
Clear sync context on test that requires it to be absent (#2026)
It turns out that occasionally, the test thread ends up with its SynchronizationContext.Current set to the Windows Forms sync context. That's bad because nothing runs a message loop, so when AsyncSubject attempts to complete an awaited operation, it tries to do so by posting a message to a queue that's never going to be processed. So we explicitly set the context to null for the test that expects that.
1 parent 6499c8e commit c4b34f3

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

Rx.NET/Source/tests/Tests.System.Reactive/Tests/TaskLikeSupportTest.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,28 @@ private async ITaskObservable<int> ManOrBoy_Throw(int n, int d)
5757
//
5858
// When we switched to MSTest, and before we had added the tests to run both with and
5959
// without the SynchronizationContext (meaning we only tested without one) this test
60-
// started failing intermittently. This seems likely to be indicative of a subtle bug in
61-
// Rx, because there doesn't seem to be any obvious reason why this should be expected to
62-
// deadlock in the absence of a synchronization context. It doesn't fail if you run the
63-
// test in isolation. It only happens when running all the tests, and even then it often
64-
// doesn't. Since we modified the build to apply a default timeout to all tests with the
65-
// aim of trying to work out which tests were occasionally locking up, the failures have
66-
// not yet recurred, suggesting that there's some sort of race condition here that's finely
67-
// balanced enough to be affected by test settings. Maybe there's some subtle reason why
68-
// you should never attempt to do what this test is doing without a
69-
// SynchronizationContext, but if so, it's unclear what that might be.
70-
// Issue https://github.com/dotnet/reactive/issues/1885 is tracking this until we
71-
// resolve the root cause of the occasional failures.
60+
// started failing intermittently. It eventually became apparent that this was because
61+
// some test somewhere in the system is setting SynchronizationContext.Current to contain
62+
// a WindowsFormsSynchronizationContext. That's why this test explicitly sets it to
63+
// null - if a UI-based context is present, the test will hang because it will attempt
64+
// to use that context to handle completion but nothing will be running a message loop,
65+
// so completion never occurs. (It's intermittent because the order in which tests run
66+
// is not deterministic, so sometimes when this test runs, the SynchronizationContext
67+
// was already null.)
7268

7369
[TestMethod]
7470
public async Task BasicsNoSynchronizationContext()
7571
{
76-
Assert.Equal(45, await ManOrBoy_Basics());
72+
var ctx = SynchronizationContext.Current;
73+
try
74+
{
75+
SynchronizationContext.SetSynchronizationContext(null);
76+
Assert.Equal(45, await ManOrBoy_Basics());
77+
}
78+
finally
79+
{
80+
SynchronizationContext.SetSynchronizationContext(ctx);
81+
}
7782
}
7883

7984
[TestMethod]

0 commit comments

Comments
 (0)