วิธีการเข้าถึงทรัพยากรที่ใช้ร่วมกันในสภาพแวดล้อมแบบเธรดที่ปรับให้ตรงกัน โดยใช้ Visual c#

การแปลบทความ การแปลบทความ
หมายเลขบทความ (Article ID): 816161 - ผลิตภัณฑ์ที่เกี่ยวข้องในบทความนี้
ขยายทั้งหมด | ยุบทั้งหมด

เนื้อหาบนหน้านี้

สรุป

คุณสามารถทำงานหลายในโปรแกรมประยุกต์ Microsoft Visual c# ในเวลาเดียวกัน โดยใช้เธรด Multithreading สามารถเริ่มการทำงานเธรดอื่นเพื่อทำงานที่แตกต่างกันในเวลาเดียวกัน Multithreading ยังช่วยเพิ่มประสิทธิภาพและการตอบสนองของโปรแกรมประยุกต์ของคุณ

เนื่องจากเธรดหลายสามารถเข้าถึงทรัพยากรในเวลาเดียวกัน คุณอาจต้องการซิงโครไนส์ของเธรดที่แต่ละกับส่วนอื่น ๆ ของโปรแกรมของคุณ บทความนี้อธิบายสถานการณ์ที่พบโดยทั่วไปบางอย่างกับเธรดการเขียนโปรแกรม และอธิบายถึงวิธีการเข้าถึงทรัพยากรที่ใช้ร่วมกันระหว่างเธรดที่หลายที่ปรับให้ตรงกัน

ช่วยป้องกันข้อมูลของคุณสากลในโมดูลในสภาพแวดล้อมที่ Multithreaded

เขตข้อมูลสาธารณะในวิธีสามารถเข้าถึงเธรดทั้งหมดที่อยู่ในโปรแกรมประยุกต์ของคุณ การซิงโครไนส์การเข้าถึงฟิลด์สาธารณะ คุณสามารถใช้คุณสมบัติแทนการใช้ฟิลด์ และใช้กับReaderWriterLockวัตถุที่มีการควบคุมการเข้าถึง โดยให้ทำตามขั้นตอนต่อไปนี้::
  1. เริ่ม Microsoft Visual Studio
  2. ในการแฟ้ม:เมนู ให้ชี้ไปที่ใหม่แล้ว คลิกProject.
  3. คลิกแสดงโครงการ c#ภายใต้ชนิดโครงการแล้ว คลิกแอพลิเคชันของคอนโซลภายใต้แม่แบบ.

    หมายเหตุ:ใน Visual Studio 2005 หรือ ใน Visual Studio 2008 คลิกvisual c#ภายใต้ชนิดโครงการแล้ว คลิกแอพลิเคชันของคอนโซลภายใต้แม่แบบ.
  4. ในการชื่อ:กล่องข้อความ ชนิดMultiThreadApplicationแล้ว คลิกตกลง.
  5. เปลี่ยนรหัสที่มีอยู่กับรหัสต่อไปนี้ใน Class1.cs

    หมายเหตุ:ใน Visual Studio 2005 และ Visual Studio 2008 แฟ้มเริ่มต้นคือ Program.cs
    using System;
    using System.Threading;
    
    namespace MultiThreadApplication
    {
    	class Class1
    	{
    		private ReaderWriterLock rwl = new ReaderWriterLock();
    		private long myNumber;
    		public long Number   // the Number property
    		{
    			get
    			{
    				//Acquire a read lock on the resource.
    				rwl.AcquireReaderLock(Timeout.Infinite);                
    				try
    				{
    					Console.WriteLine("Thread:{0} starts getting the Number", Thread.CurrentThread.GetHashCode());
    					Thread.Sleep(50);
    					Console.WriteLine("Thread:{0} got the Number", Thread.CurrentThread.GetHashCode());
    
    				}
    				finally
    				{
    					//Release the lock.
    					rwl.ReleaseReaderLock();
    				}
    				return myNumber;
    			}
    			set
    			{
    				//Acquire a write lock on the resource.
    				rwl.AcquireWriterLock(Timeout.Infinite);
    				try
    				{
    					Console.WriteLine("Thread: {0} start writing the Number", Thread.CurrentThread.GetHashCode());
    					Thread.Sleep(50);
    					myNumber = value;
    					Console.WriteLine("Thread: {0} written the Number", Thread.CurrentThread.GetHashCode());
    				}
    				finally
    				{
    					//Release the lock.
    					rwl.ReleaseWriterLock();
    				}
    			}
    		}
    		
    		[STAThread]
    		static void Main(string[] args)
    		{
    			Thread []threadArray = new Thread[20]; 
    			int threadNum;
    
    
    			Class1 Myclass = new Class1();
    			ThreadStart myThreadStart = new ThreadStart(Myclass.AccessGlobalResource);
    
    			//Create 20 threads.
    			for( threadNum = 0; threadNum < 20; threadNum++)
    			{
    				threadArray[threadNum] = new Thread(myThreadStart);
    			}
    
    			//Start the threads.
    			for( threadNum = 0; threadNum < 20; threadNum++)
    			{   
    				threadArray[threadNum].Start();
    			}
    
    			//Wait until all the thread spawn out finish.
    			for( threadNum = 0; threadNum < 20; threadNum++)
    				threadArray[threadNum].Join();
    
    			Console.WriteLine("All operations have completed. Press enter to exit");
    			Console.ReadLine();
    		}
    
    		public void AccessGlobalResource()
    		{
    			Random rnd = new Random();
    			long theNumber;
    			
    			if (rnd.Next() % 2 != 0)
    				theNumber = Number;
    			else
    			{
    				theNumber = rnd.Next();
    				Number = theNumber;
    			}
    
    		}
    	}
    }
    
  6. สร้างโครงการ และเรียกใช้โปรแกรมประยุกต์

ช่วยให้คุณทำเซฟเธรดคลาของคุณ

หลายเธรดอาจพยายามเข้าถึงวัตถุในเวลาเดียวกัน เมื่อเธรดมากกว่าหนึ่งแข่งขันสำหรับการเข้าถึงวัตถุในเวลาเดียวกัน เธรดบางอย่างอาจได้รับสถานะที่ไม่ถูกต้องหากเธรดอื่นปรับเปลี่ยนทรัพยากรในเวลาเดียวกัน ตัวอย่างเช่น ถ้าเธรดอ่านฟิลด์ของวัตถุในขณะที่เธรดอื่นปรับเปลี่ยนฟิลด์ เธรดแรกอาจได้รับสถานะไม่ถูกต้องของฟิลด์ สถานการณ์นี้เป็นชื่อแย่ง

เมื่อต้องการหลีกเลี่ยงสถานการณ์เช่นนี้ คุณสามารถช่วยป้องกันส่วนสำคัญของรหัสของเงื่อนไขแข่ง โดยใช้การล็อก ล็อก แสดง โดย Visual c# คำสำคัญล็อกงบ ช่วยให้เธรดเดียวของการดำเนินการเพื่อขอรับสิทธิ์ในการดำเนินการเฉพาะบนวัตถุ ขั้นตอนต่อไปนี้ของตัวอย่างสาธิตล็อก:
  1. เปิด Visual Studio
  2. ในการแฟ้ม:เมนู ให้ชี้ไปที่ใหม่แล้ว คลิกProject.
  3. คลิกแสดงโครงการ c#ภายใต้ชนิดโครงการแล้ว คลิกแอพลิเคชันของคอนโซลภายใต้แม่แบบ.

    หมายเหตุ:ใน Visual Studio 2005 หรือ ใน Visual Studio 2008 คลิกvisual c#ภายใต้ชนิดโครงการแล้ว คลิกแอพลิเคชันของคอนโซลภายใต้แม่แบบ.
  4. ในการชื่อ:กล่องข้อความ ชนิดMultiThreadLockApplicationแล้ว คลิกตกลง.
  5. แทนรหัสที่มีอยู่ ด้วยรหัสต่อไปนี้ใน Class1.cs:
    using System;
    using System.Threading;
    
    namespace MultiThreadLockApplication
    {
    	class Student
    	{
    		private static string myTeacherName = "Bill";
    		private string myName = "Grace";
    		private static object somePrivateStaticObject = new Object();
    
    		public static string TeacherName
    		{
    			get
    			{
    				string theName;
    
    				// Synchronize access to the shared member.
    				lock(somePrivateStaticObject)
    				{
    					Console.WriteLine("Thread {0} starts to get the teacher's name",Thread.CurrentThread.GetHashCode());
    					theName = myTeacherName;
    
    					// Wait for 0.3 second.
    					Thread.Sleep(300);
    					Console.WriteLine("Thread {0} finished to get the teacher's name:{1}.", Thread.CurrentThread.GetHashCode(), theName);
    				}
    				return theName;
    			}
    
    			set
    			{
    				lock(somePrivateStaticObject)
    				{
    					Console.WriteLine("Thread {0} starts to set the teacher's name.", Thread.CurrentThread.GetHashCode());
    					myTeacherName = value;
    
    					// Wait for 0.3 second.
    					Thread.Sleep(300);
    					Console.WriteLine("Thread {0} finished to set the teacher's name:{1}.", Thread.CurrentThread.GetHashCode(), value);
    				}
    			}
    		}
    
    		public string GetName()
    		{
    			string theName;
    			lock(this)
    			{
    				Console.WriteLine("Thread {0} starts to get the student's name.", Thread.CurrentThread.GetHashCode());
    				theName = myName;
    
    				// Wait for 0.3 second.
    				Thread.Sleep(300);
    				Console.WriteLine("Thread {0} finished to get the student's name:{1}", Thread.CurrentThread.GetHashCode(), theName);
    				return theName;
    			}
    		}
    
    		public string SetName(string NewName)
    		{
    			string theOldName;
    			lock(this)
    			{
    				Console.WriteLine("Thread {0} starts to set the student's name.", Thread.CurrentThread.GetHashCode());
    				theOldName = myName;
    				myName = NewName;
    
    				// Wait for 0.3 second.
    				Thread.Sleep(300);
    				Console.WriteLine("Thread {0} finished to set the student's name:{1}", Thread.CurrentThread.GetHashCode(), NewName);
    			}
    			return theOldName;
    		}
    	}
    
    	class Class1
    	{
    		public static int WorkItemNum = 20;
    		public static AutoResetEvent Done = new AutoResetEvent(false);
    
    		public static void AccessClassResource(object state)
    		{
    			Random rnd = new Random();
    			string theName;
    			Student AStudent = (Student) state;
    
    			if( (rnd.Next() %2) != 0)
    			{
    				if( (rnd.Next() %2) != 0)
    				{
    					switch (rnd.Next() %3 )
    					{
    						case 0:
    							Student.TeacherName = "Tom";
    							break;
    						case 1:
    							Student.TeacherName = "Mike";
    							break;
    						case 2:
    							Student.TeacherName = "John";
    							break;
    					}
    				}
    				else
    				{
    					theName = Student.TeacherName;
    				}
    			}
    			else
    			{
    				if( (rnd.Next() %2) != 0)
    				{
    					switch (rnd.Next() %3 )
    					{
    						case 0:
    							AStudent.SetName("Janet");
    							break;
    						case 1:
    							AStudent.SetName("David");
    							break;
    						case 2:
    							AStudent.SetName("Ben");
    							break;
    					}
    				}
    				else
    				{
    					theName = AStudent.GetName();
    				}
    			}
    
    			if(Interlocked.Decrement( ref WorkItemNum) == 0)
    			{
    				Done.Set();
    			}
    		}
    
    		[STAThread]
    		static void Main(string[] args)
    		{
    			int threadNum;
    			Student AStudent = new Student();
    
    			// Queue up 20 work items in the ThreadPool.
    			for (threadNum = 0 ; threadNum <= WorkItemNum -1 ; threadNum++) 
    			{
    				ThreadPool.QueueUserWorkItem(new WaitCallback(AccessClassResource),AStudent);
    			}
    
    			Done.WaitOne();
    			Console.WriteLine("All operations have completed. Press enter to exit");
    			Console.ReadLine();
    		}
    	}
    }
  6. สร้างโครงการ และเรียกใช้โปรแกรมประยุกต์

ข้อมูลอ้างอิง

สำหรับข้อมูลเพิ่มเติม ให้ดูเว็บไซต์ของ Microsoft สำหรับนักพัฒนาเครือข่าย (MSDN) ต่อไปนี้:
เธรด Pooling
.aspx http://msdn2.microsoft.com/en-us/library/0ka9477y (vs.71)
ReaderWriterLock
.aspx http://msdn2.microsoft.com/en-us/library/bz6sth95 (vs.71)
คลาสของ ReaderWriterLock
.aspx http://msdn2.microsoft.com/en-us/library/system.threading.readerwriterlock (vs.71)

คุณสมบัติ

หมายเลขบทความ (Article ID): 816161 - รีวิวครั้งสุดท้าย: 14 มกราคม 2554 - Revision: 3.0
ใช้กับ
  • Microsoft Visual C# 2008 Express Edition
  • Microsoft Visual C# 2005 Express Edition
  • Microsoft Visual C# .NET 2003 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
Keywords: 
kbthreadsync kbthread kbhowtomaster kbmt KB816161 KbMtth
แปลโดยคอมพิวเตอร์
ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:816161

ให้ข้อเสนอแนะ

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com