public void TestPerformance()
 {
     ContextStack<int> contextStack = new ContextStack<int>();
     Stopwatch s = new Stopwatch();
     s.Start();
     Parallel.For(0, Loops, i =>
                                {
                                    using (contextStack.Region(i))
                                    {
                                        Assert.AreEqual(i, contextStack.Current);
                                    }
                                });
     s.Stop();
     Trace.WriteLine(s.ToString("{0} loops", Loops));
 }
Exemple #2
0
        public void TestPerformance()
        {
            ContextStack <int> contextStack = new ContextStack <int>();
            Stopwatch          s            = new Stopwatch();

            s.Start();
            Parallel.For(0, Loops, i =>
            {
                using (contextStack.Region(i))
                {
                    Assert.AreEqual(i, contextStack.Current);
                }
            });
            s.Stop();
            Trace.WriteLine(s.ToString("{0} loops", Loops));
        }
        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));
        }
Exemple #4
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));
        }