C #: Bagaimana jika metode statis dipanggil dari beberapa utas?

93

Dalam Aplikasi saya, saya memiliki metode statis yang dipanggil dari beberapa utas secara bersamaan. Apakah ada bahaya jika data saya tercampur?

Dalam upaya pertama saya, metode ini tidak statis dan saya membuat beberapa instance kelas. Dalam hal ini, data saya entah bagaimana tercampur. Saya tidak yakin bagaimana ini terjadi karena itu hanya terjadi kadang-kadang. Saya masih men-debug. Tetapi sekarang metode ini statis. Saya tidak memiliki masalah sejauh ini. Mungkin itu hanya keberuntungan. Saya tidak tahu pasti.

TalkingCode
sumber

Jawaban:

96

Variabel yang dideklarasikan di dalam metode (dengan kemungkinan pengecualian variabel " ditangkap ") diisolasi, jadi Anda tidak akan mendapatkan masalah bawaan; namun, jika metode statis Anda mengakses status bersama apa pun, semua taruhan dibatalkan.

Contoh keadaan bersama adalah:

  • bidang statis
  • objek yang diakses dari cache umum (tidak berseri)
  • data yang diperoleh melalui parameter masukan (dan status pada objek tersebut), jika memungkinkan bahwa beberapa utas menyentuh objek yang sama

Jika Anda telah berbagi status, Anda harus:

  • Berhati-hatilah untuk tidak mengubah status setelah dapat dibagikan (lebih baik: gunakan objek yang tidak dapat diubah untuk merepresentasikan status, dan ambil snapshot status ke dalam variabel lokal - yaitu daripada mereferensikan whatever.SomeDataberulang kali, Anda membaca whatever.SomeData sekali ke dalam variabel lokal, dan kemudian cukup gunakan variabel - perhatikan bahwa ini hanya membantu untuk keadaan yang tidak dapat diubah!)
  • menyinkronkan akses ke data (semua utas harus disinkronkan) - baik yang saling eksklusif atau (lebih terperinci) pembaca / penulis
Marc Gravell
sumber
1
@Diego - apakah komentar itu ditujukan untuk saya, atau untuk @Holli?
Marc Gravell
Kepada Holli, sekadar menambahkan beberapa info praktis pada balasan Anda.
Diego Pereyra
1
@ Marc Saya tidak sepenuhnya setuju dengan "Variabel yang dideklarasikan di dalam metode (dengan kemungkinan pengecualian variabel" ditangkap ") diisolasi". Pertimbangkan pegangan file yang dideklarasikan dalam metode statis. Kemudian satu utas dapat mengakses pegangan ketika beberapa utas lain menggunakannya. Ini akan menyebabkan perilaku yang tidak terduga. Atau apakah variabel "yang diambil" berarti "pegangan file" juga.
prabhakaran
9
@prabhakaran jika pegangan file adalah variabel metode, itu hanya dibatasi untuk pemanggil itu. Penelepon lain akan berbicara dengan variabel yang berbeda (variabel metode adalah per panggilan). Sekarang, akses ke file yang mendasarinya adalah masalah terpisah, tetapi itu tidak terkait dengan c # atau .NET. Jika pegangan tidak dibagikan, orang akan mengharapkan semacam mutex / lock jika skenario ini mungkin terjadi.
Marc Gravell
29

Ya, itu hanya keberuntungan. ;)

Tidak masalah apakah metode tersebut statis atau tidak, yang penting adalah apakah datanya statis atau tidak.

Jika setiap utas memiliki instance kelasnya sendiri yang terpisah dengan kumpulan datanya sendiri, tidak ada risiko data tercampur. Jika datanya statis, hanya ada satu kumpulan data, dan semua utas berbagi data yang sama, jadi tidak ada cara untuk tidak mencampurnya.

Jika data Anda dalam instance terpisah masih tercampur, kemungkinan besar karena datanya tidak benar-benar terpisah.

Guffa
sumber
7
Mencintai baris itu - It doesn't matter if the method is static or not, what matters is if the data is static or not. Sebagai tambahan, variabel lokal yang dideklarasikan dalam lingkup metode statis tidak membentuk bagian data yang perlu kita khawatirkan dalam skenario yang diberikan.
RBT
jawaban yang bagus. Banyak membantu.
Fractal
15

Metode statis seharusnya bagus untuk beberapa utas.

Di sisi lain, data statis dapat menyebabkan masalah karena upaya untuk mengakses data yang sama dari utas yang berbeda perlu dikontrol untuk memastikan bahwa hanya satu utas pada satu waktu yang membaca atau menulis data.

Doug Ferguson
sumber
2
Kata kunci di sini adalah sinkronisasi :-)
G. Stoynev
2
membaca
Freestyle076
9

MSDN Selalu mengatakan:

Semua anggota publik statis (Dibagikan dalam Visual Basic) jenis ini adalah thread aman. Setiap anggota instance tidak dijamin aman untuk thread.

Sunting: Seperti yang dikatakan orang-orang di sini, tidak selalu terjadi, dan jelas ini berlaku untuk kelas yang dirancang dengan cara ini di BCL, bukan untuk kelas yang dibuat pengguna di mana ini tidak berlaku.

Marcote
sumber
3
Fiuh! Akhirnya, saya mengerti arti dari catatan ini yang sering ditemukan dalam dokumentasi MSDN. Jadi pada dasarnya, ketika MS mendesain metode statis (di mana catatan ini diterbitkan) di BCL, mereka tidak mengakses variabel / anggota / status apa pun yang berada di luar cakupan metode itu. Mereka bergantung sepenuhnya pada variabel lokal cakupan metode hanya untuk mengimplementasikan logika metode itu. Sangat senang Anda berbagi.
RBT
@Marcote, bukankah sebaliknya? Anggota instance aman karena ada satu per instance. Namun, anggota statis tidak aman untuk thread karena mereka dibagikan di antara semua instance kelas itu? quora.com/…
Fractal
1
tergantung. Saya tidak akan pernah memperlakukan anggota instance aman secara default. Itulah mengapa seluruh kumpulan pustaka dan untuk menghindari korupsi data di antara banyak hal lainnya.
Marcote
1
oke, Terima kasih @Marcote. Saya perlahan-lahan menyadari bahwa saya harus banyak belajar.
Fractal