Comment faire pour synchroniser l'accès à une ressource partagée dans un environnement de multithreading à l'aide de Visual C#

IMPORTANT : Cet article est issu d'une traduction automatique réalisée par un logiciel Microsoft et non par un traducteur professionnel. Cette traduction automatique a pu aussi être révisée par la communauté Microsoft grâce à la technologie Community Translation Framework (CTF). Pour en savoir plus sur cette technologie, veuillez consulter la page http://support.microsoft.com/gp/machine-translation-corrections/fr. Microsoft vous propose en effet des articles traduits par des professionnels, des articles issus de traductions automatiques et des articles issus de traductions automatiques révisées par la communauté Microsoft, de manière à ce que vous ayez accès à tous les articles de notre Base de connaissances dans votre langue. Il est important de noter que les articles issus de la traduction automatique, y compris ceux révisés par la communauté Microsoft, peuvent contenir des erreurs de vocabulaire, de syntaxe ou de grammaire. Microsoft ne pourra être tenu responsable des imprécisions, erreurs, ainsi que de tout dommage résultant d’une traduction incorrecte du contenu ou de son utilisation par les clients.

La version anglaise de cet article est la suivante: 816161
Pour obtenir une version Microsoft Visual Basic .NET de cet article, reportez-vous à la section. 316136.

DANS CETTE TÂCHE

Résumé
Vous pouvez effectuer plusieurs tâches dans les applications Microsoft Visual C# en même temps en utilisant le multithreading. Le multithreading peut démarrer plusieurs threads pour effectuer des tâches différentes en même temps. Le multithreading améliore également les performances et la réactivité de vos applications.

Étant donné que plusieurs threads peuvent accéder à une ressource en même temps, vous souhaiterez synchroniser différents threads avec d'autres parties de votre programme. Cet article décrit certains scénarios courants avec la programmation multithread et explique comment faire pour synchroniser l'accès à une ressource partagée entre plusieurs threads.

retour en haut

Pour protéger vos données globales des modules dans un environnement multithread

Les champs publics dans les méthodes sont accessibles à tous les threads dans votre application. Pour synchroniser l'accès aux champs publics, vous pouvez utiliser la propriété au lieu de champ et un objet ReaderWriterLock permet de contrôler l'accès. Pour ce faire, procédez comme suit :
  1. Démarrez Microsoft Visual Studio.
  2. Dans le menu fichier , pointez sur Nouveau, puis cliquez sur projet.
  3. Cliquez surProjets Visual C# sous Types de projets, puis cliquez sur Application Console sousmodèles.

    Remarque Dans Visual Studio 2005 ou dans Visual Studio 2008, cliquez sur Visual C# sous les Types de projet, puis cliquez sur Application Console sousmodèles.
  4. Dans la zone de texte nom , tapezMultiThreadApplication, puis cliquez surOK.
  5. Remplacez le code existant par le inClass1.cs de code suivant.

    Remarque Dans Visual Studio 2005 et Visual Studio 2008, le fichier par défaut est 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. Générez le projet et exécutez l'application.
retour en haut

Vous aider à rendre votre classe de Thread-Safe

Plusieurs threads peuvent tenter d'accéder à un objet en même temps. Lorsque plusieurs threads sont en concurrence pour l'accès à un objet en même temps, certains threads peuvent recevoir un état non valide si un autre thread modifie la ressource en même temps. Par exemple, si un thread lit le champ de l'objet alors qu'un autre thread modifie le champ, le premier thread peut recevoir un état non valide du champ. Cette situation s'appelle une condition de concurrence critique.

Pour éviter cette situation, vous pouvez aider à protéger des sections critiques de votre code des conditions de concurrence critique en utilisant des verrous. Un verrou, représenté par le Visual C# mot clé instruction lock, permet à un seul thread d'exécution d'obtenir des droits d'exécution exclusifs sur un objet. L'exemple qui suit montre verrous :
  1. Ouvrez Visual Studio.
  2. Dans le menu fichier , pointez sur Nouveau, puis cliquez sur projet.
  3. Cliquez surProjets Visual C# sous Types de projets, puis cliquez sur Application Console sousmodèles.

    Remarque Dans Visual Studio 2005 ou dans Visual Studio 2008, cliquez sur Visual C# sous les Types de projet, puis cliquez sur Application Console sousmodèles.
  4. Dans la zone de texte nom , tapezMultiThreadLockApplication, puis cliquez surOK.
  5. Remplacez le code existant par le inClass1.cs de code suivants :
    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. Générez le projet et exécutez l'application.
retour en haut
Références
Pour plus d'informations, consultez les sites Web de Microsoft Developer Network (MSDN) suivant :retour en haut

Avertissement : Cet article a été traduit automatiquement.

Propriétés

ID d'article : 816161 - Dernière mise à jour : 01/03/2015 04:23:00 - Révision : 4.0

Microsoft Visual C# 2008 Express Edition, Microsoft Visual C# 2005 Express Edition, Microsoft Visual C# .NET 2003 Initiation, Microsoft Visual C# .NET 2002 Initiation

  • kbthreadsync kbthread kbhowtomaster kbmt KB816161 KbMtfr
Commentaires