Beispiel #1
0
 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));
     });
 }
Beispiel #2
0
        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));
        }