⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 circularbuffer.cs

📁 this is a good book for the visual c#
💻 CS
字号:
// Fig. 14.6: CircularBuffer.cs
// Implementing the producer/consumer relationship with a
// circular buffer.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace CircularBuffer
{
   // implement the shared integer with synchronization
   public class HoldIntegerSynchronized
   {
      // each array element is a buffer
      private int[] buffers = { -1, -1, -1 };

      // occupiedBufferCount maintains count of occupied buffers
      private int occupiedBufferCount = 0;

      // variable that maintain read and write buffer locations
      private int readLocation = 0, writeLocation = 0;
      
      // GUI component to display output
      private TextBox outputTextBox;

      // constructor
      public HoldIntegerSynchronized( TextBox output )
      {
         outputTextBox = output;
      }

      // property Buffer
      public int Buffer
      {
         get
         {
            // lock this object while getting value 
            // from buffers array
            lock ( this )
            {
               // if there is no data to read, place invoking 
               // thread in WaitSleepJoin state
               if ( occupiedBufferCount == 0 )
               {
                  outputTextBox.Text += "\r\nAll buffers empty. " + 
                     Thread.CurrentThread.Name + " waits.";
                  outputTextBox.ScrollToCaret();

                  Monitor.Wait( this );
               }

               // obtain value at current readLocation, then 
               // add string indicating consumed value to output
               int readValue = buffers[ readLocation ];

               outputTextBox.Text += "\r\n" + 
                  Thread.CurrentThread.Name + " reads " + 
                  buffers[ readLocation ] + " ";

               // just consumed a value, so decrement number of 
               // occupied buffers
               --occupiedBufferCount;

               // update readLocation for future read operation,
               // then add current state to output
               readLocation = 
                  ( readLocation + 1 ) % buffers.Length;
               outputTextBox.Text += CreateStateOutput();
               outputTextBox.ScrollToCaret();

               // return waiting thread (if there is one) 
               // to Started state
               Monitor.Pulse( this );

               return readValue;

            } // end lock

         } // end accessor get

         set
         {
            // lock this object while setting value 
            // in buffers array
            lock ( this )
            {
               // if there are no empty locations, place invoking
               // thread in WaitSleepJoin state
               if ( occupiedBufferCount == buffers.Length )
               {
                  outputTextBox.Text += "\r\nAll buffers full. " + 
                     Thread.CurrentThread.Name + " waits.";
                  outputTextBox.ScrollToCaret();

                  Monitor.Wait( this );
               }

               // place value in writeLocation of buffers, then
               // add string indicating produced value to output
               buffers[ writeLocation ] = value;

               outputTextBox.Text += "\r\n" + 
                  Thread.CurrentThread.Name + " writes " + 
                  buffers[ writeLocation ] + " ";

               // just produced a value, so increment number of 
               // occupied buffers
               ++occupiedBufferCount;

               // update writeLocation for future write operation,
               // then add current state to output
               writeLocation = 
                  ( writeLocation + 1 ) % buffers.Length;
               outputTextBox.Text += CreateStateOutput();
               outputTextBox.ScrollToCaret();

               // return waiting thread (if there is one) 
               // to Started state
               Monitor.Pulse( this );

            } // end lock

         } // end accessor set

      } // end property Buffer

      // create state output
      public string CreateStateOutput()
      {
         // display first line of state information
         string output = "(buffers occupied: " + 
            occupiedBufferCount + ")\r\nbuffers: ";

         for ( int i = 0; i < buffers.Length; i++ )
            output += " " + buffers[ i ] + "  ";

         output += "\r\n";

         // display second line of state information
         output += "         ";

         for ( int i = 0; i < buffers.Length; i++ )
            output += "---- ";

         output += "\r\n";

         // display third line of state information
         output += "         ";

         // display readLocation (R) and writeLocation (W)
         // indicators below appropriate buffer locations
         for ( int i = 0; i < buffers.Length; i++ ) 

            if ( i == writeLocation && 
               writeLocation == readLocation ) 
               output += " WR  ";
            else if ( i == writeLocation )
               output += " W   ";
            else if  ( i == readLocation ) 
               output += "  R  ";
            else
               output += "     ";

         output += "\r\n";

         return output;
      }

   } // end class HoldIntegerSynchronized

   // produce the integers from 11 to 20 and place them in buffer
   public class Producer
   {
      private HoldIntegerSynchronized sharedLocation;
      private TextBox outputTextBox;
      private Random randomSleepTime;

      // constructor
      public Producer( HoldIntegerSynchronized shared, 
         Random random, TextBox output )
      {
         sharedLocation = shared;
         outputTextBox = output;
         randomSleepTime = random;
      }

      // produce values from 11-20 and place them in 
      // sharedLocation's buffer
      public void Produce()
      {
         // sleep for random interval upto 3000 milliseconds
         // then set sharedLocation's Buffer property
         for ( int count = 11; count <= 20; count++ )
         {
            Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
            sharedLocation.Buffer = count;
         }

         string name = Thread.CurrentThread.Name;

         outputTextBox.Text += "\r\n" + name +
            " done producing.\r\n" + name + " terminated.\r\n";
         
         outputTextBox.ScrollToCaret();

      } // end method Produce

   } // end class Producer

   // consume the integers 1 to 10 from circular buffer
   public class Consumer
   {
      private HoldIntegerSynchronized sharedLocation;
      private TextBox outputTextBox;
      private Random randomSleepTime;

      // constructor
      public Consumer( HoldIntegerSynchronized shared,
         Random random, TextBox output )
      {
         sharedLocation = shared;
         outputTextBox = output;
         randomSleepTime = random;
      }

      // consume 10 integers from buffer
      public void Consume()
      {
         int sum = 0;

         // loop 10 times and sleep for random interval upto 
         // 3000 milliseconds then add sharedLocation's 
         // Buffer property value to sum
         for ( int count = 1; count <= 10; count++ )
         {
            Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
            sum += sharedLocation.Buffer;
         }

         string name = Thread.CurrentThread.Name;
         
         outputTextBox.Text += "\r\nTotal " + name + 
            " consumed: " + sum + ".\r\n" + name + 
            " terminated.\r\n";

         outputTextBox.ScrollToCaret();

      } // end method Consume

   } // end class Consumer

   // set up the producer and consumer and start them
   public class CircularBuffer : System.Windows.Forms.Form
   {
      private System.Windows.Forms.TextBox outputTextBox;
      /// <summary>
      /// Required designer variable.
      /// </summary>
      private System.ComponentModel.Container components = null;

      // no-argument constructor
      public CircularBuffer()
      {
         InitializeComponent();
      }

      /// <summary>
      /// Clean up any resources being used.
      /// </summary>
      protected override void Dispose( bool disposing )
      {
         if( disposing )
         {
            if (components != null) 
            {
               components.Dispose();
            }
         }
         base.Dispose( disposing );
      }

		#region Windows Form Designer generated code
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {
         this.outputTextBox = new System.Windows.Forms.TextBox();
         this.SuspendLayout();
         // 
         // outputTextBox
         // 
         this.outputTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
         this.outputTextBox.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
         this.outputTextBox.Multiline = true;
         this.outputTextBox.Name = "outputTextBox";
         this.outputTextBox.ReadOnly = true;
         this.outputTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
         this.outputTextBox.Size = new System.Drawing.Size(304, 461);
         this.outputTextBox.TabIndex = 0;
         this.outputTextBox.Text = "";
         // 
         // CircularBuffer
         // 
         this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
         this.ClientSize = new System.Drawing.Size(304, 461);
         this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                      this.outputTextBox});
         this.Name = "CircularBuffer";
         this.Text = "CircularBuffer";
         this.Load += new System.EventHandler(this.CircularBuffer_Load);
         this.ResumeLayout(false);

      }
		#endregion

      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main() 
      {
         Application.Run( new CircularBuffer() );
      }

      // Load event handler creates and starts threads
      private void CircularBuffer_Load( 
         object sender, System.EventArgs e )
      {
         // create shared object
         HoldIntegerSynchronized sharedLocation = 
            new HoldIntegerSynchronized( outputTextBox );

         // display sharedLocation state before producer
         // and consumer threads begin execution
         outputTextBox.Text = sharedLocation.CreateStateOutput();

         // Random object used by each thread
         Random random = new Random();

         // create Producer and Consumer objects
         Producer producer = 
            new Producer( sharedLocation, random, outputTextBox );
         Consumer consumer =
            new Consumer( sharedLocation, random, outputTextBox );

         // create and name threads
         Thread producerThread = 
            new Thread( new ThreadStart( producer.Produce ) );
         producerThread.Name = "Producer";

         Thread consumerThread = 
            new Thread( new ThreadStart( consumer.Consume ) );
         consumerThread.Name = "Consumer";

         // start threads
         producerThread.Start();
         consumerThread.Start();

      } // end CircularBuffer_Load method

   } // end class CircularBuffer
}

/*
 ************************************************************************** 
 * (C) Copyright 2002 by Deitel & Associates, Inc. and Prentice Hall.     *
 * All Rights Reserved.                                                   *
 *                                                                        *
 * DISCLAIMER: The authors and publisher of this book have used their     *
 * best efforts in preparing the book. These efforts include the          *
 * development, research, and testing of the theories and programs        *
 * to determine their effectiveness. The authors and publisher make       *
 * no warranty of any kind, expressed or implied, with regard to these    *
 * programs or to the documentation contained in these books. The authors *
 * and publisher shall not be liable in any event for incidental or       *
 * consequential damages in connection with, or arising out of, the       *
 * furnishing, performance, or use of these programs.                     *
 **************************************************************************
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -