Advertisement
Guest User

Untitled

a guest
Jun 8th, 2012
992
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Threading;
  5. using System.Windows.Threading;
  6.  
  7. namespace TestingConsoleApplication.Tests.ThreadedQueue
  8. {
  9.     class ThreadedQueueTest
  10.     {
  11.         public ThreadedQueueTest()
  12.         {
  13.             Debug.WriteLine("App Thread ID: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
  14.  
  15.             TaskQueue taskQueue = new TaskQueue();
  16.             QueueManager queueManager = new QueueManager(taskQueue);
  17.  
  18.             // inter thread exchanger object
  19.             InterThreadExchanger exchanger = new InterThreadExchanger();
  20.             exchanger.TaskQueue = taskQueue;
  21.  
  22.             // create queue listening thread
  23.             Thread processingThread = new Thread(new Processor().ProcessingThreadBody);
  24.             processingThread.Start(exchanger);
  25.  
  26.             // Create an inferred delegate that invokes methods for the timer.
  27.             TimerCallback tcb = queueManager.AddTask;
  28.  
  29.             Timer stateTimer = new Timer(tcb, null, 1000, 1000);
  30.             Console.ReadLine();
  31.  
  32.             stateTimer.Change(0, 0);
  33.  
  34.             Console.WriteLine("Final task queue status: " + taskQueue.Count.ToString());
  35.             Debug.WriteLine("App Thread ID on end: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
  36.  
  37.             Console.ReadLine();
  38.         }
  39.     }
  40.  
  41.     /// <summary>
  42.     /// Processing thread working object
  43.     /// </summary>
  44.     class Processor
  45.     {
  46.         InterThreadExchanger exchanger;
  47.         Dispatcher processorDispatcher;
  48.        
  49.         /// <summary>
  50.         /// Processing thread main method
  51.         /// </summary>
  52.         public void ProcessingThreadBody(object interThreadExchanger)
  53.         {
  54.             processorDispatcher = Dispatcher.CurrentDispatcher;
  55.             exchanger = (InterThreadExchanger)interThreadExchanger;
  56.             exchanger.TaskQueue.Filled += new TaskQueue.TaskQueueFilledEventHandler(OnTaskQueueFilled);
  57.  
  58.             Debug.WriteLine("Processor Thread ID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
  59.             Debug.WriteLine("Processor Dispatcher Thread ID: " + processorDispatcher.Thread.ManagedThreadId.ToString());
  60.             Debug.Assert(processorDispatcher.Thread.ManagedThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId, "Processor thread ID and its dispatcher thread ID are not equal!");
  61.         }
  62.  
  63.         /// <summary>
  64.         /// Queue filled event listener
  65.         /// </summary>
  66.         /// <param name="sender"></param>
  67.         /// <param name="args"></param>
  68.         void OnTaskQueueFilled(object sender, EventArgs args)
  69.         {
  70.             Debug.WriteLine("Processor QueueListener caller Thread ID: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
  71.             Debug.WriteLine("Processor Dispatcher Thread ID: " + processorDispatcher.Thread.ManagedThreadId.ToString());
  72.  
  73.             if (processorDispatcher.CheckAccess())
  74.             {
  75.                 Debug.WriteLine("Processor calling ProcessQueue.");
  76.                 ProcessQueue();
  77.             }
  78.             else
  79.             {
  80.                 Debug.WriteLine("Processor invoking ProcessQueue.");
  81.                 processorDispatcher.BeginInvoke(new Action(ProcessQueue), new object[] {null});
  82.                 Debug.WriteLine("Processor invoked ProcessQueue.");
  83.             }
  84.         }
  85.  
  86.         void ProcessQueue()
  87.         {
  88.             Debug.WriteLine("ProcessQueue Thread ID: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
  89.  
  90.             foreach (string Task in exchanger.TaskQueue)
  91.             {
  92.                 Console.WriteLine("Task in queue: " + Task);
  93.  
  94.                 // todo: process task
  95.  
  96.                 lock (exchanger.TaskQueue)
  97.                 {
  98.                     exchanger.TaskQueue.Dequeue();
  99.                 }
  100.             }
  101.         }
  102.     }
  103.  
  104.     /// <summary>
  105.     /// Interthread communication object
  106.     /// </summary>
  107.     class InterThreadExchanger
  108.     {
  109.         ConnectionState connectionState = ConnectionState.Ready;
  110.        
  111.         public enum ConnectionState
  112.         {
  113.             Ready,
  114.             Broken
  115.         }
  116.        
  117.         public TaskQueue TaskQueue { get; set; }
  118.         public ConnectionState DbConnectionState
  119.         {
  120.             get
  121.             {
  122.                 return connectionState;
  123.             }
  124.             set
  125.             {
  126.                 if (connectionState != value)
  127.                 {
  128.                     connectionState = value;
  129.                     RaiseConnectionStateChangeEvent();
  130.                 }
  131.             }
  132.         }
  133.  
  134.         public delegate void ConnectionStateChangeEventHandler(object sender, EventArgs args);
  135.         public event ConnectionStateChangeEventHandler ConnectionStateChange;
  136.  
  137.         void RaiseConnectionStateChangeEvent()
  138.         {
  139.             if (ConnectionStateChange != null)
  140.             {
  141.                 ConnectionStateChange(this, new EventArgs());
  142.             }
  143.         }
  144.     }
  145.  
  146.     class QueueManager
  147.     {
  148.         TaskQueue taskQueue;
  149.  
  150.         public QueueManager(TaskQueue taskQueue)
  151.         {
  152.             this.taskQueue = taskQueue;
  153.             Console.WriteLine("Thread id (StatusChecker): " + System.Threading.Thread.CurrentThread.ManagedThreadId);
  154.         }
  155.  
  156.         // This method is called by the timer delegate.
  157.         public void AddTask(Object stateInfo)
  158.         {
  159.             Console.WriteLine("Thread id (Timer elapsed): " + System.Threading.Thread.CurrentThread.ManagedThreadId);
  160.  
  161.             lock (taskQueue)
  162.             {
  163.                 taskQueue.Enqueue("New task name");
  164.             }
  165.  
  166.             Console.WriteLine("Task count: " + taskQueue.Count.ToString());
  167.         }
  168.     }
  169.  
  170.     class TaskQueue : Queue<string>
  171.     {
  172.         Object queueLock = new Object();
  173.        
  174.         public TaskQueue()
  175.         {
  176.             Console.WriteLine("Thread id (TaskQueue):" + System.Threading.Thread.CurrentThread.ManagedThreadId);
  177.         }
  178.  
  179.         public new void Enqueue(string item)
  180.         {
  181.             // if task is already queued, skip adding
  182.             if (!Contains(item))
  183.             {
  184.                 Console.WriteLine("Adding taks: " + item);
  185.                 lock (queueLock) // thread safety
  186.                 {
  187.                     base.Enqueue(item);
  188.                 }
  189.                 RaiseEvent();
  190.             }
  191.             else
  192.             {
  193.                 Console.WriteLine("Item already queued: " + item);
  194.             }
  195.         }
  196.  
  197.         void RaiseEvent()
  198.         {
  199.             if (Filled != null)
  200.             {
  201.                 Filled(this, new EventArgs());
  202.             }
  203.         }
  204.  
  205.         public delegate void TaskQueueFilledEventHandler(object sender, EventArgs args);
  206.         public event TaskQueueFilledEventHandler Filled;
  207.    }
  208. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement