public CustomAwaitable(string url) { ctx = SynchronizationContext.Current; this.task = TaskEx.RunEx( () => { var req = (HttpWebRequest)WebRequest.Create(url); req.Method = "HEAD"; var resp = (HttpWebResponse)req.GetResponse(); return(this.FormatHeaders(resp.Headers)); }); }
public void TestAsync() { const int taskCount = 5000; // Create an asynchronous context in which to run. AsyncContext.Run( async() => { Task[] tasks = new Task[taskCount]; for (int a = 0; a < taskCount; a++) { tasks[a] = TaskEx.RunEx( async() => { ContextStack <string> stack = new ContextStack <string>(); TaskCompletionSource tcs1 = new TaskCompletionSource(); TaskCompletionSource tcs2 = new TaskCompletionSource(); TaskCompletionSource tcs3 = new TaskCompletionSource(); string randomString = Guid.NewGuid().ToString(); string randomString2 = Guid.NewGuid().ToString(); using (stack.Region(randomString)) { // Check we have 'A' in the current stack. Assert.AreEqual(randomString, stack.Current); Assert.AreEqual(1, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.Last()); int threadId = Thread.CurrentThread.ManagedThreadId; // Await the task await TaskEx.Delay(500); // Check we still have 'A' in the current stack. Assert.AreEqual(randomString, stack.Current); Assert.AreEqual(1, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.Last()); // Create new thread. Task task = TaskEx.RunEx( async() => { int task2Thread = Thread.CurrentThread.ManagedThreadId; // Assess if this is a new thread if (threadId != task2Thread) { Interlocked.Increment(ref _task2NewThread); } // Check we have 'A' in the current stack. Assert.AreEqual(randomString, stack.Current); Assert.AreEqual(1, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.Last()); // Wait for the first signal await tcs1.Task; // Check we still have 'A' in the current stack (i.e. we're not affected by additions in first thread. Assert.AreEqual(randomString, stack.Current); Assert.AreEqual(1, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.Last()); // Add C to stack. using (stack.Region("C")) { // We should have A, C in stack now. Assert.AreEqual("C", stack.Current); Assert.AreEqual(2, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.First()); // Second signal tcs2.SetResult(); // Wait for the 3rd signal await tcs3.Task; // We should still have A, C in stack now. Assert.AreEqual("C", stack.Current); Assert.AreEqual(2, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.First()); } // Back to just having C. Assert.AreEqual(randomString, stack.Current); Assert.AreEqual(1, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.Last()); // Wait a bit before finishing. await TaskEx.Delay(100); if (task2Thread != Thread.CurrentThread.ManagedThreadId) { Interlocked.Increment( ref _task2ThreadSwitch); } }); // Add B to stack. using (stack.Region(randomString2)) { // We should have A, B in stack now. Assert.AreEqual(randomString2, stack.Current); Assert.AreEqual(2, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.First()); // Signal 2nd task with first signal. tcs1.SetResult(); // Wait for 2nd task to signal back with 2nd second. await tcs2.Task; // We should still have A, B in stack now. Assert.AreEqual(randomString2, stack.Current); Assert.AreEqual(2, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.First()); // Signal 2nd task with third signal tcs3.SetResult(); // Wait for task to finish. await task; // We should still have A, B in stack now. Assert.AreEqual(randomString2, stack.Current); Assert.AreEqual(2, stack.CurrentStack.Count()); Assert.AreEqual(randomString, stack.CurrentStack.First()); } // We should just have A in stack. Assert.AreEqual(randomString, stack.Current); Assert.AreEqual(1, stack.CurrentStack.Count()); if (threadId != Thread.CurrentThread.ManagedThreadId) { Interlocked.Increment(ref _task1ThreadSwitch); } } // The stack should be empty Assert.IsNull(stack.Current); Assert.AreEqual(0, stack.CurrentStack.Count()); }); } await TaskEx.WhenAll(tasks); }); Trace.WriteLine( String.Format( "Task1 Thread Switch: {1}{0}Task2 Thread Switch: {2}{0}Task2 new thread: {3}{0}Total tasks: {4}", Environment.NewLine, _task1ThreadSwitch, _task2ThreadSwitch, _task2NewThread, taskCount)); }