C #: Birden çok evreden statik bir yöntem çağrılırsa ne olur?


95

Uygulamamda aynı anda birden çok iş parçacığından çağrılan statik bir yöntemim var. Verilerimin karışması tehlikesi var mı?

İlk denememde yöntem statik değildi ve sınıfın birden çok örneğini oluşturuyordum. Bu durumda verilerim bir şekilde karıştı. Bunun nasıl olduğundan emin değilim çünkü sadece bazen oluyor. Hala hata ayıklama yapıyorum. Ama şimdi yöntem statiktir, şu ana kadar hiçbir sorunum yok. Belki sadece şanstır. Kesin olarak bilmiyorum.


Yanıtlar:


99

Yöntemlerin içinde bildirilen değişkenler (" yakalanan " değişkenlerin olası istisnası dışında ) yalıtılmıştır, böylece herhangi bir doğal problem yaşamazsınız; ancak, statik yönteminiz herhangi bir paylaşılan duruma erişirse, tüm bahisler kapalıdır.

Paylaşılan duruma örnekler:

  • statik alanlar
  • ortak bir önbellekten erişilen nesneler (serileştirilmemiş)
  • birden çok iş parçacığının aynı nesneye / nesnelere dokunması mümkünse, girdi parametreleri aracılığıyla elde edilen veriler (ve bu nesnelerdeki durum)

Durumu paylaştıysanız, şunlardan birini yapmalısınız:

  • durumu bir kez paylaşıldıktan sonra değiştirmemeye dikkat edin (daha iyisi: durumu temsil etmek için sabit nesneler kullanın ve durumun anlık görüntüsünü yerel bir değişkene alın - yani whatever.SomeDatatekrar tekrar referans vermek yerine , yerel bir değişkeni bir whatever.SomeData kez okursunuz ve sonra sadece değişkeni kullanın - bunun yalnızca değişmez durum için yardımcı olduğuna dikkat edin!)
  • verilere erişimi senkronize edin (tüm iş parçacıkları senkronize olmalıdır) - ya karşılıklı olarak dışlayıcı ya da (daha ayrıntılı) okuyucu / yazıcı

1
@Diego - bu yorum bana mı yoksa @Holli'ye mi yönelik?
Marc Gravell

Holli'ye, cevabınıza bazı pratik bilgiler eklemek için.
Diego Pereyra

1
@Marc "Yöntemler içinde bildirilen değişkenler (" yakalanan "değişkenlerin olası istisnası dışında) izole edilmiş" e tam olarak katılamıyorum. Statik bir yöntemde bildirilen bir dosya tanıtıcısı düşünün. Daha sonra bir iş parçacığı, onu kullanan başka bir iş parçacığı tutamaca erişebilir. Beklenmedik davranışlara yol açacaktır. Veya "yakalanan" değişkeniniz de "dosya tanıtıcı" anlamına mı geliyor?
prabhakaran

9
@prabhakaran, eğer bir dosya tanıtıcısı bir yöntem değişkeni ise, kapsamı yalnızca o arayanı kapsamaktadır. Başka herhangi bir arayan, farklı bir değişkenle konuşacaktır (yöntem değişkenleri arama başınadır). Şimdi, temeldeki dosyaya erişim ayrı bir sorundur, ancak bunun c # veya .NET ile ilgisi yoktur. Eğer tanıtıcı paylaşılmamışsa, bu senaryo muhtemelse, bir tür muteks / kilit beklenebilir.
Marc Gravell

29

Evet, sadece şans. ;)

Yöntemin statik olup olmaması önemli değildir, önemli olan verilerin statik olup olmadığıdır.

Her iş parçacığının kendi veri kümesine sahip kendi ayrı sınıf örneği varsa, verilerin karıştırılma riski yoktur. Veriler statikse, yalnızca bir veri kümesi vardır ve tüm iş parçacıkları aynı verileri paylaşır, dolayısıyla bunları karıştırmamanın bir yolu yoktur.

Verileriniz ayrı durumlarda hala karışıyorsa, bunun nedeni büyük olasılıkla verilerin gerçekten ayrı olmamasıdır.


7
Bu satırı sevdim - It doesn't matter if the method is static or not, what matters is if the data is static or not. Sadece eklemek gerekirse, statik bir yöntem kapsamında bildirilen yerel değişkenler, verilen senaryoda rahatsız edilmemiz gereken verilerin bir kısmını oluşturmaz.
RBT

mükemmel cevap. Çok yardımcı oldu.
Fractal

15

Statik yöntemler, birden çok iş parçacığı için iyi olmalıdır.

Öte yandan, statik veriler bir soruna neden olabilir, çünkü aynı verilere farklı iş parçacıklarından erişme girişimlerinin, bir seferde yalnızca bir iş parçacığının verileri okuduğundan veya yazdığından emin olmak için kontrol edilmesi gerekir.


2
Buradaki anahtar kelime senkronizasyon :-)
G. Stoynev

2
okuma aynı anda gerçekleşebilir, ancak aynı anda okumak VE yazmak beklenmedik davranışlara yol açacaktır
Serbest

10

MSDN her zaman şunu söylüyor:

Bu türdeki tüm genel statik (Visual Basic'te Paylaşılan) üyeler iş parçacığı açısından güvenlidir. Herhangi bir örnek üyesinin iş parçacığı güvenli olduğu garanti edilmez.

Düzenleme: Buradaki adamların dediği gibi, her zaman durum böyle değildir ve açıkça bu, BCL'de bu şekilde tasarlanan sınıflar için geçerlidir, bunun geçerli olmadığı kullanıcı tarafından oluşturulan sınıflar için değil.


3
Vay be! Son olarak, MSDN belgelerinde çok sık bulunan bu notun anlamını anladım. Dolayısıyla, temel olarak, MS BCL'de statik bir yöntem tasarladığında (bu notun yayınlandığı yerde), bu yöntemin kapsamı dışındaki herhangi bir değişkene / üyeye / duruma erişmezler. Yalnızca bu yöntemin mantığını uygulamak için yöntem kapsamlı yerel değişkenlere tamamen güvenirler. Paylaştığına çok sevindim.
RBT

@Marcote, tersi doğru değil mi? Örnek üyeleri güvenlidir çünkü örnek başına bir tane vardır. Ancak, statik üyeler o sınıfın tüm örnekleri arasında paylaşıldıkları için iş parçacığı açısından güvenli değiller mi? quora.com/…
Fractal

1
değişir. Varsayılan olarak bir örnek üyesine asla güvenli davranmam. Bu yüzden bir dizi kitaplık ve diğer birçok şeyin yanı sıra veri bozulmasını önlemek için.
Marcote

1
tamam, teşekkürler @Marcote. Öğrenecek çok şeyim olduğunu yavaş yavaş anlıyorum.
Fractal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.