2013-04-07 15 views
8

znaczy, jeśli mam następujący blok na kod C#:Wyjątki wewnątrz bloku zamka

public class SynchedClass 
{ 
    public void addData(object v) 
    { 
     lock(lockObject) 
     { 
      //Shall I worry about catching an exception here? 

      //Do the work 
      //arr.Add(v); 
     } 
    } 
    private List<object> arr = new List<object>(); 
    private object lockObject = new object(); 
} 

postaram się złapać wyjątki wewnątrz bloku lock? (Moją główną obawą jest to, że wyjątek może zostać podniesiony wewnątrz blokady, co uniemożliwi odblokowanie blokady.)

Odpowiedz

20

Blokada zostanie zwolniona, gdy wyjątek ucieknie z bloku blokującego.

To dlatego lock(){...} to tłumaczyć przez kompilator z grubsza na:

Monitor.Enter(obj); 
try{ 

// contents of the lock block 

}finally{ 
    Monitor.Exit(obj); 
} 
+0

Więc sposób, w jaki napisałem powyżej, powinien być dobry, prawda? – c00000fd

+1

Jeśli w końcu złapiesz wyjątek gdzieś na stosie wywołań, to powinno być OK. W przeciwnym razie Twoja aplikacja się zawiesi :) – alex

1

Oświadczenie blokady w postaci „zamka (x) ...” gdzie x jest wyrazem typu referencyjnego, jest właśnie odpowiednik (C# 4.0):

bool entered = false; 
try { 
    System.Threading.Monitor.Enter(x, ref entered); 
    ... 
} 
finally { if (entered) System.Threading.Monitor.Exit(x); } 
1

Jest więcej do rozważenia niż tylko zwolnienie muteksa.

Wyjątek występujący przy lock zwolni blokadę, ale w jakim stanie jest program? Wątek czekający na blokadę będzie się teraz budził i być może teraz będzie miał do czynienia z nieprawidłowym stanem. Jest to trudny problem bez idealnego rozwiązania.

Najlepszą rzeczą jest próba utrzymania zamków na tyle małych, na ile jest to możliwe i wywoływania metod, które nie są rzucane. (To ignorowanie elepanta w pokoju, który jest zło ​​ThreadAbortException ...)

Aby dobrze omówić te problemy, zobacz artykuł Erica Lipperta: Locks and exceptions do not mix.

+0

Tak, łatwiej powiedzieć niż zrobić. Nie sądzę, że istnieje jedna metoda .NET, która nie wzbudza jakiegoś wyjątku. – c00000fd

Powiązane problemy