2010-08-25 19 views
10

Yalnızca bir iş parçacığına engelleme olmayan erişimi uygulayan aşağıdaki işlevi göz önünde bulundurun. BuradaMonitor.TryEnter kullanma ve kilitleme nesnesiyle ilgili soru

public bool TryCancelGroup() 
{ 
    if (Monitor.TryEnter(_locked)) 
    { 
     if (_locked == false) 
     { 
      _locked = true; 

      try 
      { 
       // do something 
      } 
      catch (Exception ex) 
      { 
       _locked = false; 
      } 
      finally 
      { 
       Monitor.Exit(_locked); 
      } 
     } 
     return _locked; 
    } 
    else 
    { 
     return false; 
    } 
} 

Ve _locked değişken tanımlanır nasıl. Program Monitor.Exit(_locked); ulaştığında

bool _locked = false; 

Şimdi önce eşitlenmedi değişkeni _locked bir System.Threading.SynchronizationLockException deyişi atar. Ben bu istisna başlarken boolean bayrak olarak kullanmak amacıyla bool için bunu değiştiğinde

Tüm değişkeni _locked zaman önce çalışan nesne

object _locked = new object(); 

olarak tanımlandı edildi.

+1

JaredPar sorununuza için çare olmuştur. Fakat mantığınız hatalı görünüyor - eğer ekrana _locked = true ile girerseniz monitörden asla çıkmayacaksınız. – VinayC

+0

Kesinlikle evet, teşekkürler VinayC –

+0

Ayrıca, genellikle kilit olarak statik bir nesneye sahip olduğunuzu düşünüyorum. – Chris

cevap

20

Bu nedenle neden Monitor yöntemlerinin tümü System.Object parametresini alır. Bir bool'u ilettiğinizde, Object'a dönüştürmek için bir kutu gereklidir. Kutu işlemi, her çağrı için yeni bir System.Object değeri üretir. Yani TryEnter ve Exit yöntemleri, farklı nesneleri ve istisnada sonuçları görür.

_lockedObject'a yazıldığında, kutuya gerek yoktur. Bu nedenle, TryEnter ve Exit yöntemleri aynı nesneyi görür ve doğru şekilde çalışabilir.

  • TryEnter nihayet engellemek bir olmalıdır Çık çağrısı her durumda ve aklı uğruna Çıkışta eşleştirilmesi gerekir kodu ile ilgili kısa diğer yorumlar. Aksi halde, bir kilitlenme senaryosunu
  • davet ediyorsunuz. _locked değişkeni, bir istisna karşısında yalnızca false olarak ayarlanmıştır. Eğer yürütme bir istisna oluşturmazsa, gerçek kalır ve hiçbir iplik tekrar if bloğuna girmez.
+0

Evet, eminim. Ama System.Object türetilmiş bool türü değil mi? Yani, Object'ten türetilir, ancak yine de Object'e bir dönüşüm bir yerlerde yerine getirildiğinde, bir boks operasyonu kullanılır? Bu ifade doğru mu? –

+3

@Captain, "bool" dahil herhangi bir türdeki bir değer türü "System.Object" veya bir arabirime yazılan bir konumda kullanıldığında, bir boks işlemi gerçekleşir. – JaredPar

4

0'a bir montior üzerinde zaman aşımı ayarlamak, istediğiniz davranışı uygulamak yardımcı olabilir. Kilitlemek için genel olarak bildirilen bir nesne kullanın.

static object mylock = new object(); 

....

if (Monitor.TryEnter(mylock, 0)) 
{ 
    try 
    { 
      // Do work 
    } 
    finally 
    { 
     Monitor.Exit(mylock); 
    } 
} 
+2

Monitor.TryEnter (mylock, 0), reflektörde görebildiğim kadarıyla Monitor.TryEnter (mylock) ile aynıdır. – Chris

+0

Deneyimlerimden değil. Benim için "0" ı ekledim ve sahip olduğum problemi çözdüm. –

+0

@Andrew 'statik nesne var mylock' geçerli değişken bildirimi değil. – tchelidze