Co się stanie, jeśli wrócę przed zakończeniem korzystania z instrukcji? Czy dyspozycja zostanie wywołana?
Mam następujący kod
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
Metoda dispose()
jest wywoływana na końcu using
wyrażenia }
prawda? Skoro I return
przed zakończeniem using
, czy obiekt MemoryStream
będzie prawidłowo usuwany? Co tu się dzieje?
5 answers
Tak, Dispose
zostanie wywołany. Jest wywoływany, gdy tylko wykonanie opuści zakres bloku using
, niezależnie od tego, jakie środki trzeba było opuścić blok, czy to koniec wykonania bloku, Instrukcja return
, czy wyjątek.
Jak słusznie zauważył @Noldorin, użycie using
bloku w kodzie jest kompilowane do try
/finally
, z wywołaniem Dispose
w bloku finally
. Na przykład następujący kod:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
Skutecznie staje się:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Więc, ponieważ finally
jest gwarantowane wykonanie po zakończeniu wykonywania bloku try
, niezależnie od jego ścieżki wykonania, Dispose
jest gwarantowane wywołanie, bez względu na wszystko.
Aby uzyskać więcej informacji, zobacz Ten artykuł MSDN .
dodatek:
Małe zastrzeżenie do dodania: ponieważ Dispose
jest gwarantowane wywołanie, prawie zawsze dobrym pomysłem jest upewnienie się, że Dispose
nigdy nie wyrzuca wyjątku podczas implementacji IDisposable
. Niestety, są zajęcia w biblioteka bazowa, która robi wrzuca w pewnych okolicznościach, gdy Dispose
jest wywołana -- patrzę na Ciebie, WCF Service Reference / Client Proxy! -- i wtedy może być bardzo trudno wyśledzić oryginalny wyjątek, jeśli {[2] } został wywołany podczas odwijania stosu wyjątków, ponieważ oryginalny wyjątek zostaje połknięty na rzecz nowego wyjątku wygenerowanego przez wywołanie Dispose
. To może być szalenie frustrujące. Czy to frustrujące? Jeden z dwóch. Może jedno i drugie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-14 15:33:44
using
instrukcje zachowują się dokładnie jak bloki try ... finally
, więc zawsze będą wykonywane na dowolnych ścieżkach wyjścia kodu. Uważam jednak, że są one przedmiotem bardzo niewielu i rzadkich sytuacji, w których finally
bloki nie są wywoływane. Jednym z przykładów, który pamiętam, jest to, czy wątek pierwszoplanowy kończy się, gdy wątki tła są aktywne: wszystkie wątki oprócz GC są wstrzymane, co oznacza, że finally
bloki nie są uruchamiane.
Oczywisty edit: zachowują się tak samo poza logiką, która pozwala im obsługiwać IDisposable objects, d ' Oh.
Zawartość bonusowa: mogą być ułożone w stos (gdzie typy się różnią):
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
Oraz rozdzielane przecinkami (gdzie typy są takie same):
using (SqlCommand comm = new SqlCommand("", conn),
comm2 = new SqlCommand("", conn))
{
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-24 21:42:24
Twój obiekt MemoryStream zostanie usunięty prawidłowo, nie musisz się o to martwić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-14 15:17:23
Za pomocą instrukcji using
obiekt zostanie usunięty niezależnie od ścieżki zakończenia.
Czytaj dalej...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-14 15:17:49
Spójrz na swój kod w reflector po skompilowaniu go. Przekonasz się, że kompilator refakturuje kod, aby upewnić się, że dispose jest wywoływany w strumieniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-14 15:18:21