private static TaskCompletionSource <T> Create <T>(SourceOrign origin) { switch (origin) { case SourceOrign.NewTCS: return(new TaskCompletionSource <T>()); case SourceOrign.Create: return(TaskSource.Create <T>(null)); default: throw new ArgumentOutOfRangeException(nameof(origin)); } }
public void VerifyIsSyncSafe(SourceOrign origin) { var source = Create <int>(origin); // Yes this looks stupid, but it's the proper pattern for how we statically init now // ...and if we're dropping NET45 support, we can just nuke it all. #if NET462 Assert.True(TaskSource.IsSyncSafe(source.Task)); #elif NETCOREAPP2_0 Assert.True(TaskSource.IsSyncSafe(source.Task)); #endif }
public void TestContinuationHijacking(SourceOrign origin, AttachMode attachMode, bool expectHijack) { TaskCompletionSource <int> source = Create <int>(origin); int settingThread = Environment.CurrentManagedThreadId; var state = new AwaitState(); state.Attach(source.Task, attachMode); source.TrySetResult(123); state.Wait(); // waits for the continuation to run int from = state.Thread; Assert.NotEqual(-1, from); // not set if (expectHijack) { Assert.True(settingThread == from, "expected hijack; didn't happen"); } else { Assert.False(settingThread == from, "setter was hijacked"); } }
public void VerifyIsSyncSafe(SourceOrign origin, bool expected) { var source = Create <int>(origin); Assert.AreEqual(expected, TaskSource.IsSyncSafe(source.Task)); }