tag:blogger.com,1999:blog-5422036137568788209.post8501104642873637698..comments2023-02-28T12:04:19.260+03:00Comments on handcode: Об Exception в блоке usingИлья Дубаденкоhttp://www.blogger.com/profile/03756815679135463187noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-5422036137568788209.post-12466995853645655042010-02-17T17:27:09.098+03:002010-02-17T17:27:09.098+03:00Всем спасибо за комментарии, добавил два обновлени...Всем спасибо за комментарии, добавил два обновления в статью.Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-23402865184669082952010-02-17T15:22:22.352+03:002010-02-17T15:22:22.352+03:00Странно, при коменте съелись определения генериков...Странно, при коменте съелись определения генериков < T ><br />Но я думаю, суть и так ясна.eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-75593499981063896602010-02-17T15:17:58.369+03:002010-02-17T15:17:58.369+03:00Лично мне сразу пришла в голову идея наваять вот т...Лично мне сразу пришла в голову идея наваять вот такой враппер на такие случаи.<br /><br />public class SafeDisposeWrapper : IDisposable<br /> where T : IDisposable<br /> {<br /> public SafeDisposeWrapper(T @object, Action destructorExHandler)<br /> {<br /> Object = @object;<br /> _destructorExHandler = destructorExHandler;<br /> }<br /><br /> public T Object { get; private set; }<br /><br /> public void Dispose()<br /> {<br /> try<br /> {<br /> Object.Dispose();<br /> }<br /> catch (Exception e)<br /> {<br /> if (_destructorExHandler != null)<br /> _destructorExHandler(e);<br /> }<br /> finally<br /> {<br /> GC.SuppressFinalize(this);<br /> }<br /> }<br /><br /> private readonly Action _destructorExHandler;<br /> }<br /><br /><br />Используется как-то так:<br /><br />Some some;<br /> using (new SafeDisposeWrapper(some = new Some(),<br /> e => Console.WriteLine("Ololo!!! Teh destructor exception: {0}", e.ToString())))<br /> {<br /> try<br /> {<br /> some.SomeMethod();<br /><br /> throw new Exception();<br /> }<br /> catch (Exception e)<br /> {<br /> // тут хендлим наш важный ексепшн<br /> }<br /> }<br /><br /><br /><br />ПС. оказывается, в предыдущем коменте это уже было. Зря старался :)eugenehttps://www.blogger.com/profile/07698068563747362766noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-88547528600559174662010-02-17T13:02:28.189+03:002010-02-17T13:02:28.189+03:00@_FRED_
Спасибо за ссылку, фактически моя статья о...@_FRED_<br />Спасибо за ссылку, фактически моя статья описывает так называемый "Exception masking".<br />Кстасти, было интересно прочитать про "safe IDisposable wrapper": http://marcgravell.blogspot.com/2008/11/dontdontuse-using.htmlИлья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-67334439154227946522010-02-17T12:43:09.670+03:002010-02-17T12:43:09.670+03:00Кстати, вот ещё немного собранной вместе информаци...Кстати, вот ещё немного собранной вместе информации по данному вопросу и один из способов решения той же задачи: http://blog.hypercomplex.co.uk/index.php/2009/11/should-dispose-throw-exceptions/Anonymoushttps://www.blogger.com/profile/11725153141467656623noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-74544958780755449212010-02-17T12:24:42.621+03:002010-02-17T12:24:42.621+03:00Ага, я невнимательно вчитался. Ну что поделаешь: п...Ага, я невнимательно вчитался. Ну что поделаешь: писатели сами себе бяки :о)<br /><br />За них то, что нужно сказал Джо (http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae, поиск по "Avoid throwing an exception from within Dispose")<br /><br />Оговорка про "critical situations" там смотрится очень странно, так как в таких ситуациях ("leaks, inconsistent shared state, etc.") впору завершать процесс, ибо гарантировать корректную работу после такого сбоя проблематично.<br /><br />Приведённый пример с WCF больше напоминает недоработку в дизайне, и бороться надо с недоработкой. Например, можно или не реализовывать IDisposable, если не можешь реализовать его корректно или, если сделать Dispose() пустым, обязав коллера вызывать явный Close() и ловить исключения.<br /><br />Думать о том, как бороться с исключениями, брошенными файнализатором ещё более бессмысленно: без спец. настроек приложение завершится.<br /><br />Собственно, я всё о том, что лучше пропагандировать то, почему из файнализаторов, Dispose() и finally нельзя бросать исключения, а не то, как с этим можно жить.Anonymoushttps://www.blogger.com/profile/11725153141467656623noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-47077797614087328682010-02-17T11:23:05.775+03:002010-02-17T11:23:05.775+03:00Вы не правильно поняли, статья немного о том.
Это ...Вы не правильно поняли, статья немного о том.<br />Это правило, которое Вы привели из MSDN, определяет, что при повторном(multiple times) вызове метода Dispose никаких исключений не должно быть. При этом предполагалось, что Dispose при первом и последующих вызовах отработает корректно.Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-74131233288697907102010-02-17T10:29:16.996+03:002010-02-17T10:29:16.996+03:00Есть очень простое правило на счёт исключений в ID...Есть очень простое правило на счёт исключений в IDisposable. Правило описано в МСДН к методу Dispose:<br /><br />If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times.<br /><br />То есть Dispose() должен быть к тому, что его вызовут несколько раз и не должен бросать исключений.<br /><br />Поэтому рассуждения о том, что же будет (а тем более решения, расходящиеся с прямой настоятельной рекомендацией), если исключение случится, кажутся по меньшей мере очень странными.Anonymoushttps://www.blogger.com/profile/11725153141467656623noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-37391049290343332482010-02-16T19:26:50.510+03:002010-02-16T19:26:50.510+03:00Для WCF прокси нужно использовать немного другой п...Для WCF прокси нужно использовать немного другой подход:<br />http://msdn.microsoft.com/en-us/library/aa355056.aspxCryptohttps://www.blogger.com/profile/15811221892642720045noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-23941354503963375462010-02-16T19:20:42.842+03:002010-02-16T19:20:42.842+03:00Так же нужно учесть, если класс Some будет использ...Так же нужно учесть, если класс Some будет использован без using-а, и он вызывает using в ~Some, то exception будет отловлен уже GC.Anonymoushttps://www.blogger.com/profile/06334806575485038663noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-60997100622828416582010-02-16T19:07:34.438+03:002010-02-16T19:07:34.438+03:00Например, если Вы хотите принудительно освободить ...Например, если Вы хотите принудительно освободить ресурсы, но лучше использовать конструкцию using.Илья Дубаденкоhttps://www.blogger.com/profile/03756815679135463187noreply@blogger.comtag:blogger.com,1999:blog-5422036137568788209.post-64110217904726464882010-02-16T18:54:16.443+03:002010-02-16T18:54:16.443+03:00А в каких случаях надо самому вызывать метод Dispo...А в каких случаях надо самому вызывать метод Dispose(); ?GLeBaTihttps://www.blogger.com/profile/06111526879474829433noreply@blogger.com