Bagikan melalui


Utas terkelola dan tidak terkelola di Windows

Manajemen semua utas dilakukan melalui kelas Thread, termasuk utas yang dibuat oleh runtime bahasa umum dan yang dibuat di luar runtime yang memasuki lingkungan terkelola untuk menjalankan kode. Runtime memantau semua utas dalam prosesnya yang pernah menjalankan kode dalam lingkungan eksekusi terkelola. Ini tidak melacak utas lain. Utas dapat memasuki lingkungan eksekusi terkelola melalui interop COM (karena runtime mengekspos objek terkelola sebagai objek COM ke dunia yang tidak dikelola), fungsi COM DllGetClassObject, dan pemanggilan platform.

Saat utas yang tidak dikelola memasuki runtime melalui, misalnya, pembungkus yang dapat dipanggil COM, sistem akan memeriksa penyimpanan utas-lokal dari utas tersebut untuk mencari objek Thread yang dikelola internal. Jika ditemukan, runtime sudah mengetahui utas ini. Namun, jika tidak dapat menemukannya, runtime akan membuat objek Thread baru dan memasangnya di penyimpanan utas-lokal dari utas tersebut.

Dalam utas terkelola, Thread.GetHashCode adalah identifikasi utas terkelola yang stabil. Untuk masa pakai utas Anda, utas tidak akan bertabrakan dengan nilai dari utas lain, terlepas dari domain aplikasi tempat Anda mendapatkan nilai ini.

Pemetaan dari utas Win32 ke utas terkelola

Tabel berikut memetakan elemen utas Win32 ke perkiraan runtime yang setara. Perhatikan bahwa pemetaan ini tidak mewakili fungsionalitas yang identik. Misalnya, TerminateThread tidak menjalankan klausa finally atau mengosongkan sumber daya, dan tidak dapat dicegah. Namun, Thread.Abort menjalankan semua kode putar kembali Anda, merebut kembali semua sumber daya, dan dapat ditolak menggunakan ResetAbort. Pastikan untuk membaca dokumentasi lebih dekat sebelum membuat asumsi tentang fungsionalitas.

Dalam Win32 Dalam runtime bahasa umum
CreateThread Kombinasi Utas dan ThreadStart
TerminateThread Thread.Abort
SuspendThread Thread.Suspend
ResumeThread Thread.Resume
Tidur Thread.Sleep
WaitForSingleObject pada handel utas Thread.Join
ExitThread Tidak ada yang setara
GetCurrentThread Thread.CurrentThread
SetThreadPriority Thread.Priority
Tidak ada yang setara Thread.Name
Tidak ada yang setara Thread.IsBackground
Dekat dengan CoInitializeEx (OLE32.DLL) Thread.ApartmentState

Utas terkelola dan apartemen COM

Utas terkelola dapat ditandai untuk menunjukkan bahwa utas tersebut akan meng-host apartemen satu utas atau multiutas. (Untuk informasi selengkapnya tentang arsitektur threading COM, lihat Proses, Utas, dan Apartemen.) Metode GetApartmentState, SetApartmentState, dan TrySetApartmentState dari kelas Thread mengembalikan dan menetapkan apartemen keadaan utas. Jika status belum ditetapkan, GetApartmentState mengembalikan ApartmentState.Unknown.

Properti hanya dapat diatur ketika utas dalam status ThreadState.Unstarted; properti hanya dapat diatur sekali untuk utas.

Jika status apartemen tidak diatur sebelum utas dimulai, utas diinisialisasi sebagai apartemen multiutas (MTA). Utas finalizer dan semua utas yang dikendalikan oleh ThreadPool adalah MTA.

Penting

Untuk kode startup aplikasi, satu-satunya cara untuk mengontrol status apartemen adalah dengan menerapkan MTAThreadAttribute atau STAThreadAttribute ke prosedur titik masuk.

Objek terkelola yang diekspos ke COM berperilaku seolah-olah mereka telah mengumpulkan penyusun utas bebas. Dengan kata lain, mereka dapat dipanggil dari apartemen COM mana pun dengan cara utas bebas. Satu-satunya objek terkelola yang tidak menunjukkan perilaku utas bebas ini adalah objek yang berasal dari ServicedComponent atau StandardOleMarshalObject.

Di dunia terkelola, tidak ada dukungan untuk SynchronizationAttribute kecuali Anda menggunakan konteks dan instans terkelola yang terikat konteks. Jika Anda menggunakan Layanan Perusahaan, maka objek Anda harus berasal dari ServicedComponent (yang berasal dari ContextBoundObject).

Saat kode terkelola memanggil objek COM, kode tersebut selalu mengikuti aturan COM. Dengan kata lain, ia memanggil melalui proksi apartemen COM dan pembungkus konteks COM+ 1.0 seperti yang ditentukan oleh OLE32.

Masalah pemblokiran

Jika utas melakukan panggilan tidak terkelola ke dalam sistem operasi yang telah memblokir utas dalam kode yang tidak dikelola, runtime tidak akan mengontrolnya untuk Thread.Interrupt atau Thread.Abort. Dalam kasus Thread.Abort, runtime menandai utas untuk Batalkan dan mengendalikannya saat memasukkan kembali kode terkelola. Lebih baik bagi Anda untuk menggunakan pemblokiran terkelola daripada pemblokiran yang tidak dikelola. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers, dan sebagainya semuanya responsif terhadap Thread.Interrupt dan untuk Thread.Abort. Selain itu, jika utas Anda berada di apartemen berutas tunggal, semua operasi pemblokiran terkelola ini akan memompa pesan dengan benar di apartemen Anda saat utas Anda diblokir.

Utas dan serat

Model utas .NET tidak mendukung serat. Anda tidak boleh memanggil fungsi tidak terkelola apa pun yang diimplementasikan dengan menggunakan serat. Panggilan tersebut dapat mengakibatkan crash runtime .NET.

Lihat juga