Πώς μπορείτε να συγχρονίσετε την πρόσβαση σε έναν κοινόχρηστο πόρο σε ένα περιβάλλον multithreading χρησιμοποιώντας το Visual C#

Μεταφράσεις άρθρων Μεταφράσεις άρθρων
Αναγν. άρθρου: 816161 - Δείτε τα προϊόντα στα οποία αναφέρεται το συγκεκριμένο άρθρο.
Ανάπτυξη όλων | Σύμπτυξη όλων

Σε αυτήν τη σελίδα

Περίληψη

Μπορείτε να εκτελέσετε πολλές εργασίες στις εφαρμογές Microsoft Visual C# ταυτόχρονα χρησιμοποιώντας multithreading. Multithreading να ξεκινήσετε διαφορετικών νημάτων για να ολοκληρώσετε διάφορες εργασίες ταυτόχρονα. Multithreading επίσης βελτιώνει τις επιδόσεις και την ανταπόκριση των εφαρμογών σας.

Επειδή πολλά νήματα να αποκτήσετε πρόσβαση σε έναν πόρο την ίδια στιγμή, μπορεί να θέλετε να συγχρονίσετε μεμονωμένα νήματα με άλλα μέρη του προγράμματος. Αυτό το άρθρο περιγράφει ορισμένα κοινά σενάρια με multithreading προγραμματισμού και εξηγεί πώς μπορείτε να συγχρονίσει την πρόσβαση σε έναν κοινόχρηστο πόρο μεταξύ πολλών νημάτων.

Βοήθεια για την προστασία της κύριας δεδομένων στις λειτουργικές μονάδες σε περιβάλλον πολλαπλών νημάτων

Τα πεδία δημόσια μεθόδους είναι δυνατή η πρόσβαση σε όλα τα νήματα της εφαρμογής σας. Για να συγχρονίσετε την πρόσβαση στα δημόσια πεδία, μπορείτε να χρησιμοποιήσετε την ιδιότητα αντί του πεδίου και χρησιμοποιούν έναReaderWriterLockτο αντικείμενο για να ελέγχετε την πρόσβαση. Για να το κάνετε αυτό, ακολουθήστε τα εξής βήματα: (Use the tools in the Windows Recovery Environment to repair Windows Vista. To do this, follow these steps:):
  1. Ξεκινήστε το Microsoft Visual Studio.
  2. Στο διακομιστήFILEμενού, σημείοΝέα, και στη συνέχεια κάντε κλικ στο κουμπίΤο έργο.
  3. Κάντε κλικΤο Visual C# έργαunderΤύποι έργου, και στη συνέχεια κάντε κλικ στο κουμπίΕφαρμογή κονσόλαςunderΠρότυπα.

    ΣΗΜΕΙΩΣΗΣτο Visual Studio 2005 ή Visual Studio 2008, κάντε κλικ στο κουμπίΤο Visual C#underΤύποι έργου, και στη συνέχεια κάντε κλικ στο κουμπίΕφαρμογή κονσόλαςunderΠρότυπα.
  4. ΣτοNAMEπλαίσιο κειμένου, πληκτρολογήστεMultiThreadApplication, και στη συνέχεια κάντε κλικ στο κουμπίOk.
  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. Build the project, and then run the application.

Help to Make Your Class Thread-Safe

Multiple threads may try to access an object at the same time. When more than one thread competes for access to an object at the same time, some threads may receive an invalid state if another thread modifies the resource at the same time. For example, if a thread reads the field of the object while another thread is modifying the field, the first thread may receive an invalid state of the field. This situation is named a race condition.

To avoid this situation, you can help to protect critical sections of your code from race conditions by using locks. A lock, represented by the Visual C# keyword lock Statement, allows a single thread of execution to obtain exclusive execution rights on an object. The following example steps demonstrate locks:
  1. Ανοίξτε το Visual Studio.
  2. Στο διακομιστήFILEμενού, σημείοΝέα, και στη συνέχεια κάντε κλικ στο κουμπίΤο έργο.
  3. Κάντε κλικΤο Visual C# έργαunderΤύποι έργου, και στη συνέχεια κάντε κλικ στο κουμπίΕφαρμογή κονσόλαςunderΠρότυπα.

    ΣΗΜΕΙΩΣΗΣτο Visual Studio 2005 ή Visual Studio 2008, κάντε κλικ στο κουμπίΤο Visual C#underΤύποι έργου, και στη συνέχεια κάντε κλικ στο κουμπίΕφαρμογή κονσόλαςunderΠρότυπα.
  4. ΣτοNAMEπλαίσιο κειμένου, πληκτρολογήστεMultiThreadLockApplication, και στη συνέχεια κάντε κλικ στο κουμπίOk.
  5. Replace the existing code with the following code in 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. Build the project, and then run the application.

Αναφορές

For more information, see the following Microsoft Developer Network (MSDN) Web sites:
Thread Pooling
http://msdn2.microsoft.com/en-us/library/0ka9477y(vs.71).aspx
ReaderWriterLock
http://msdn2.microsoft.com/en-us/library/bz6sth95(vs.71).aspx
ReaderWriterLock Class
http://msdn2.microsoft.com/en-us/library/system.threading.readerwriterlock(vs.71).aspx

Ιδιότητες

Αναγν. άρθρου: 816161 - Τελευταία αναθεώρηση: Τετάρτη, 22 Δεκεμβρίου 2010 - Αναθεώρηση: 2.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
Λέξεις-κλειδιά: 
kbthreadsync kbthread kbhowtomaster kbmt KB816161 KbMtel
Μηχανικά μεταφρασμένο
ΣΗΜΑΝΤΙΚΟ: Αυτό το άρθρο είναι προϊόν λογισμικού μηχανικής μετάφρασης της 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