Saya baru menyadari bahwa di suatu tempat dalam kode saya, saya memiliki pernyataan pengembalian di dalam kunci dan kadang di luar. Yang mana yang terbaik?
1)
void example()
{
lock (mutex)
{
//...
}
return myData;
}
2)
void example()
{
lock (mutex)
{
//...
return myData;
}
}
Yang mana yang harus saya gunakan?
c#
.net
multithreading
mutex
Patrick Desjardins
sumber
sumber
Jawaban:
Intinya, mana yang pernah membuat kode lebih sederhana. Satu titik keluar adalah ideal yang bagus, tapi saya tidak akan membengkokkan kode keluar dari bentuk hanya untuk mencapainya ... Dan jika alternatifnya mendeklarasikan variabel lokal (di luar kunci), menginisialisasi (di dalam kunci) dan lalu mengembalikannya (di luar kunci), maka saya akan mengatakan bahwa "pengembalian foo" sederhana di dalam kunci jauh lebih sederhana.
Untuk menunjukkan perbedaan dalam IL, mari kode:
(perhatikan bahwa saya akan dengan senang hati berpendapat bahwa itu
ReturnInside
adalah sedikit lebih mudah / bersih dari C #)Dan lihat IL (mode rilis dll):
Jadi pada level IL, mereka [memberi atau menerima beberapa nama] identik (saya belajar sesuatu ;-p). Dengan demikian, satu-satunya perbandingan yang masuk akal adalah hukum (sangat subyektif) gaya pengkodean lokal ... Saya lebih suka
ReturnInside
untuk kesederhanaan, tapi saya tidak akan senang dengan baik.sumber
ret
berada di dalam suatu.try
wilayah.Tidak ada bedanya; keduanya diterjemahkan ke hal yang sama oleh kompiler.
Untuk memperjelas, keduanya diterjemahkan secara efektif ke sesuatu dengan semantik berikut:
sumber
Saya pasti akan memasukkan pengembalian di dalam kunci. Kalau tidak, Anda berisiko untaian lain memasuki kunci dan memodifikasi variabel Anda sebelum pernyataan kembali, sehingga membuat penelepon asli menerima nilai yang berbeda dari yang diharapkan.
sumber
Tergantung,
Saya akan menentang gandum di sini. Saya biasanya akan kembali ke dalam kunci.
Biasanya variabel mydata adalah variabel lokal. Saya suka mendeklarasikan variabel lokal saat saya menginisialisasi mereka. Saya jarang memiliki data untuk menginisialisasi nilai saya di luar kunci saya.
Jadi perbandingan Anda sebenarnya cacat. Meskipun idealnya perbedaan antara dua opsi akan seperti yang Anda tulis, yang tampaknya memberi anggukan pada kasus 1, dalam praktiknya sedikit lebih jelek.
vs.
Saya menemukan case 2 lebih mudah dibaca dan lebih sulit untuk dikacaukan, terutama untuk cuplikan singkat.
sumber
Jika mengira kunci di luar terlihat lebih baik, tetapi berhati-hatilah jika Anda akhirnya mengubah kode menjadi:
Jika f () perlu dipanggil dengan kunci dipegang maka jelas perlu di dalam kunci, karena itu menjaga kembali di dalam kunci untuk konsistensi masuk akal.
sumber
Untuk apa nilainya, dokumentasi pada MSDN memiliki contoh untuk kembali dari dalam kunci. Dari jawaban lain di sini, tampaknya IL yang sangat mirip tetapi, bagi saya, itu tampak lebih aman untuk kembali dari dalam kunci karena dengan begitu Anda tidak menjalankan risiko variabel pengembalian ditimpa oleh utas lainnya.
sumber
Untuk membuatnya lebih mudah bagi sesama pengembang untuk membaca kode saya akan menyarankan alternatif pertama.
sumber
lock() return <expression>
pernyataan selalu:1) masukkan kunci
2) membuat toko lokal (aman-thread) untuk nilai dari jenis yang ditentukan,
3) mengisi toko dengan nilai yang dikembalikan oleh
<expression>
,4) kunci keluar
5) mengembalikan toko.
Ini berarti bahwa nilai, yang dikembalikan dari pernyataan kunci, selalu "dimasak" sebelum kembali.
Jangan khawatir
lock() return
, jangan dengarkan siapa pun di sini))sumber
Catatan: Saya yakin jawaban ini benar secara faktual dan saya harap ini membantu juga, tapi saya selalu senang memperbaikinya berdasarkan umpan balik yang konkret.
Untuk merangkum dan melengkapi jawaban yang ada:
The diterima jawaban menunjukkan bahwa, terlepas dari yang bentuk sintaks yang Anda pilih dalam Anda # C kode, dalam kode IL - dan karena itu pada saat runtime - yang
return
tidak terjadi sampai setelah mengunci dilepaskan.return
dalam satulock
blok Oleh karena itu, tegasnya, salah mengartikan aliran kontrol [1] , itu adalah sintaksis nyaman dalam hal itu menyingkirkan kebutuhan untuk menyimpan nilai kembali dalam aux. variabel lokal (dideklarasikan di luar blok, sehingga dapat digunakan dengan direturn
luar blok) - lihat jawaban Edward KMETT .Secara terpisah - dan aspek ini insidental untuk pertanyaan, tetapi mungkin masih menarik ( jawaban Ricardo Villamil mencoba mengatasinya, tetapi saya kira salah) - menggabungkan
lock
pernyataan denganreturn
pernyataan - yaitu, mendapatkan nilaireturn
dalam blok yang dilindungi dari akses bersamaan - hanya bermakna "melindungi" nilai yang dikembalikan dalam ruang lingkup penelepon jika sebenarnya tidak perlu dilindungi setelah diperoleh , yang berlaku dalam skenario berikut:Jika nilai yang dikembalikan adalah elemen dari koleksi yang hanya perlu perlindungan dalam hal menambah dan menghapus elemen, tidak dalam hal modifikasi dari elemen itu sendiri dan / atau ...
... jika nilai yang dikembalikan adalah turunan dari tipe nilai atau string .
Dalam kasus lain, penguncian harus dilakukan oleh pemanggil , bukan (hanya) di dalam metode.
[1] Theodor Zoulias menunjukkan bahwa itu secara teknis juga berlaku untuk penempatan
return
di dalamtry
,catch
,using
,if
,while
,for
, ... pernyataan; Namun, itu adalah tujuan khusus darilock
pernyataan yang cenderung mengundang pengawasan aliran kontrol yang sebenarnya, sebagaimana dibuktikan oleh pertanyaan ini yang telah ditanyakan dan telah menerima banyak perhatian.[2] Mengakses contoh tipe nilai selalu menciptakan salinan thread-local, on-the-stack; walaupun string secara teknis adalah tipe instance, mereka secara efektif berperilaku seperti-nilai tipe.
sumber
lock
, dan memperoleh makna dari penempatan pernyataan pengembalian. Yang merupakan diskusi yang tidak terkait dengan pertanyaan ini IMHO. Saya juga menemukan penggunaan "misrepresents" cukup mengganggu. Jika kembali darilock
salah mengartikan aliran kontrol, maka sama dapat dikatakan untuk kembali daritry
,catch
,using
,if
,while
,for
, dan setiap konstruk lain dari bahasa. Ini seperti mengatakan bahwa C # penuh dengan misrepresentasi aliran kontrol. Yesus ...try
,,if
... Saya pribadi bahkan cenderung untuk tidak memikirkannya, tetapi dalam kontekslock
, secara khusus, muncul pertanyaan bagi saya - dan jika itu tidak muncul untuk orang lain juga, pertanyaan ini tidak akan pernah ditanyakan , dan jawaban yang diterima tidak akan berusaha keras untuk menyelidiki perilaku yang sebenarnya.