Bagikan melalui


Thread Local Storage: Thread-Relative Static Field dan Data Slot

Anda dapat menggunakan penyimpanan lokal alur terkelola (TLS) untuk menyimpan data yang unik untuk alur dan domain aplikasi. .NET menyediakan dua cara untuk menggunakan TLS terkelola: bidang statis relatif terhadap alur dan slot data.

  • Gunakan bidang statis alur-relatif (bidang relatif terhadap alur Shared di Visual Basic) jika Anda dapat mengantisipasi kebutuhan Anda secara tepat pada waktu kompilasi. Bidang statis relatif terhadap alur memberikan performa terbaik. Mereka juga memberi Anda manfaat pemeriksaan jenis waktu kompilasi.

  • Menggunakan slot data saat persyaratan aktual Anda mungkin ditemukan hanya pada durasi. Slot data lebih lambat dan lebih canggung untuk digunakan daripada bidang statis relatif terhadap alur, dan data disimpan sebagai jenis Object, jadi Anda harus mentransmisikannya ke jenis yang benar sebelum Anda menggunakannya.

Dalam C++yang tidak dikelola, Anda menggunakan TlsAlloc untuk mengalokasikan slot secara dinamis dan __declspec(thread) untuk menyatakan bahwa variabel harus dialokasikan dalam penyimpanan relatif terhadap alur. Bidang statis dan slot data relatif terhadap alur menyediakan versi terkelola dari perilaku ini.

Anda dapat menggunakan System.Threading.ThreadLocal<T> kelas untuk membuat objek lokal terhadap alur yang diinisialisasi dengan malas saat objek pertama kali digunakan. Untuk informasi selengkapnya, lihat Inisialisasi Malas.

Keunikan Data di TLS Terkelola

Baik Anda menggunakan bidang statis atau slot data relatif alur, data di TLS terkelola unik untuk kombinasi alur dan domain aplikasi.

  • Dalam domain aplikasi, satu alur tidak dapat memodifikasi data dari alur lain, bahkan ketika kedua alur menggunakan bidang atau slot yang sama.

  • Saat alur mengakses bidang atau slot yang sama dari beberapa domain aplikasi, nilai terpisah dipertahankan di setiap domain aplikasi.

Misalnya, jika alur menetapkan nilai bidang statis relatif terhadap alur, memasukkan domain aplikasi lain, lalu mengambil nilai bidang, nilai yang diambil di domain aplikasi kedua berbeda dari nilai di domain aplikasi pertama. Mengatur nilai baru untuk bidang di domain aplikasi kedua tidak memengaruhi nilai bidang di domain aplikasi pertama.

Demikian pula, ketika alur mendapatkan slot data bernama yang sama di dua domain aplikasi yang berbeda, data di domain aplikasi pertama tetap independen dari data di domain aplikasi kedua.

Bidang Statis Relatif terhadap Alur

Jika Anda tahu bahwa sepotong data selalu unik untuk kombinasi utas dan domain aplikasi, terapkan ThreadStaticAttribute atribut ke bidang statis. Menggunakan bidang karena Anda akan menggunakan bidang statis lainnya. Data di bidang ini unik untuk setiap alur yang menggunakannya.

Bidang statis relatif terhadap alur memberikan performa yang lebih baik daripada slot data dan memiliki manfaat pemeriksaan jenis waktu kompilasi.

Ketahuilah bahwa kode konstruktor kelas apa pun akan berjalan pada alur pertama dalam konteks pertama yang mengakses bidang. Di semua alur atau konteks lain di domain aplikasi yang sama, bidang akan diinisialisasi ke null (Nothing dalam Visual Basic) jika merupakan jenis referensi, atau ke nilai defaultnya jika merupakan jenis nilai. Oleh karena itu, Anda tidak boleh mengandalkan konstruktor kelas untuk menginisialisasi bidang statis relatif alur. Sebagai gantinya, hindari menginisialisasi bidang statis relatif alur dan asumsikan bahwa bidang tersebut diinisialisasi ke null (Nothing) atau ke nilai defaultnya.

Slot Data

.NET menyediakan slot data dinamis yang unik untuk kombinasi alur dan domain aplikasi. Ada dua jenis slot data: slot bernama dan slot yang tidak disebutkan namanya. Keduanya diimplementasikan dengan menggunakan LocalDataStoreSlot struktur.

Untuk slot bernama dan tanpa nama, gunakan Thread.SetData metode dan Thread.GetData untuk mengatur dan mengambil informasi di slot. Ini adalah metode statis yang selalu bekerja pada data untuk alur yang saat ini mengeksekusinya.

Slot bernama bisa menjadi menguntunngkan, karena Anda dapat mengambil slot ketika Anda membutuhkannya dengan meneruskan namanya ke GetNamedDataSlot metode, bukan mempertahankan referensi ke slot yang tidak disebutkan namanya. Namun, jika komponen lain menggunakan nama yang sama untuk penyimpanan relatif terhadap alur dan utas menjalankan kode dari komponen Anda dan komponen lainnya, kedua komponen dapat merusak data satu sama lain. (Skenario ini mengasumsikan bahwa kedua komponen berjalan di domain aplikasi yang sama, dan bahwa mereka tidak dirancang untuk berbagi data yang sama.)

Lihat juga