Cara menyinkronkan akses ke sumber yang dipakai bersama di lingkungan multithreading dengan menggunakan Visual C#

Terjemahan Artikel Terjemahan Artikel
ID Artikel: 816161 - Melihat produk di mana artikel ini berlaku.
Perbesar semua | Perkecil semua

Pada Halaman ini

RINGKASAN

Anda dapat melakukan beberapa tugas di Microsoft Visual C# aplikasi pada waktu yang sama dengan menggunakan multithreading. Multithreading dapat memulai thread yang berbeda untuk menyelesaikan tugas yang berbeda pada waktu yang sama. Multithreading juga meningkatkan kinerja dan responsif aplikasi Anda.

Karena beberapa benang dapat mengakses sumber pada saat yang sama, Anda dapat menyinkronkan individu Thread dengan bagian-bagian lain dari program Anda. Artikel ini menjelaskan beberapa umum skenario dengan multithreading pemrograman, dan menjelaskan bagaimana untuk melakukan sinkronisasi akses ke sumber yang dipakai bersama di antara beberapa benang.

Membantu melindungi Data Anda Global dalam modul di lingkungan Multithreaded

Bidang yang umum dalam metode dapat diakses untuk semua thread dalam aplikasi Anda. Untuk menyinkronkan akses ke bidang publik, Anda dapat menggunakan properti lapangan, dan penggunaan ReaderWriterLock objek untuk mengontrol akses. Untuk melakukannya, ikuti langkah-langkah berikut:
  1. Mulai Microsoft Visual Studio.
  2. Pada Berkas menu, titik Baru, lalu klik Project.
  3. KlikVisual C# proyek di bawah Jenis proyek, dan kemudian klik Aplikasi konsol di bawahPola acu.

    Catatan Dalam Visual Studio 2005 atau Visual Studio 2008, klik Visual C# di bawah Jenis proyek, dan kemudian klik Aplikasi konsol di bawahPola acu.
  4. Dalam Nama kotak teks, ketikMultiThreadApplication, lalu klikOke.
  5. Mengganti kode yang ada dengan kode berikut dalam Class1.cs.

    Catatan Pada Visual Studio 2005 dan pada Visual Studio 2008, default file adalah 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. Membangun proyek, dan kemudian jalankan aplikasi.

Membantu untuk membuat kelas Anda Thread-aman

Beberapa benang dapat mencoba untuk mengakses objek pada saat yang sama waktu. Ketika lebih dari satu benang bersaing untuk akses ke objek pada saat yang sama, beberapa benang akan menerima status tidak sah jika lain Thread memodifikasi sumber daya pada saat yang sama. Sebagai contoh, jika sebuah thread membaca bidang objek sementara thread lain adalah mengubah bidang, thread pertama akan menerima keadaan yang tidak sah lapangan. Situasi ini bernama kondisi balapan.

Untuk menghindari situasi ini, Anda dapat membantu melindungi bagian penting dari kode dari kondisi balapan dengan menggunakan kunci. Kunci, diwakili oleh Visual C# kata kunci kunci pernyataan, memungkinkan satu benang eksekusi untuk mendapatkan hak-hak eksklusif eksekusi pada objek. Berikut langkah-langkah contoh menunjukkan kunci:
  1. Membuka Visual Studio.
  2. Pada Berkas menu, titik Baru, lalu klik Project.
  3. KlikVisual C# proyek di bawah Jenis proyek, dan kemudian klik Aplikasi konsol di bawahPola acu.

    Catatan Dalam Visual Studio 2005 atau Visual Studio 2008, klik Visual C# di bawah Jenis proyek, dan kemudian klik Aplikasi konsol di bawahPola acu.
  4. Dalam Nama kotak teks, ketikMultiThreadLockApplication, lalu klikOke.
  5. Mengganti kode yang ada dengan kode berikut dalam 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. Membangun proyek, dan kemudian jalankan aplikasi.

REFERENSI

Untuk informasi lebih lanjut, lihat Microsoft Developer Network (MSDN) Website berikut:
Benang 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 Kelas
.aspx http://msdn2.Microsoft.com/en-us/library/System.threading.readerwriterlock (vs.71)

Properti

ID Artikel: 816161 - Kajian Terakhir: 04 Oktober 2011 - Revisi: 2.0
Berlaku bagi:
  • 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
Kata kunci: 
kbthreadsync kbthread kbhowtomaster kbmt KB816161 KbMtid
Penerjemahan Mesin
PENTING: Artikel ini diterjemahkan menggunakan perangkat lunak mesin penerjemah Microsoft dan bukan oleh seorang penerjemah. Microsoft menawarkan artikel yang diterjemahkan oleh seorang penerjemah maupun artikel yang diterjemahkan menggunakan mesin sehingga Anda akan memiliki akses ke seluruh artikel baru yang diterbitkan di Pangkalan Pengetahuan (Knowledge Base) dalam bahasa yang Anda gunakan. Namun, artikel yang diterjemahkan menggunakan mesin tidak selalu sempurna. Artikel tersebut mungkin memiliki kesalahan kosa kata, sintaksis, atau tata bahasa, hampir sama seperti orang asing yang berbicara dalam bahasa Anda. Microsoft tidak bertanggung jawab terhadap akurasi, kesalahan atau kerusakan yang disebabkan karena kesalahan penerjemahan konten atau penggunaannya oleh para pelanggan. Microsoft juga sering memperbarui perangkat lunak mesin penerjemah.
Klik disini untuk melihat versi Inggris dari artikel ini:816161

Berikan Masukan

 

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