sidristij / dotnetbook Goto Github PK
View Code? Open in Web Editor NEW.NET Platform Architecture book (English, Chinese, Russian)
Home Page: http://kb.clrium.ru/ru/readme.html
License: Other
.NET Platform Architecture book (English, Chinese, Russian)
Home Page: http://kb.clrium.ru/ru/readme.html
License: Other
Здесь я предлагаю вести обсуждение главы. Ошибки, дополнения.
Здесь я предлагаю вести обсуждение главы. Ошибки, дополнения.
Когда я только начал читать, у меня в памяти всплыло что этот интерфейс предназначен для освобождения как управляемых ресурсов, которые надо освобождать, так и для неуправляемых. Именно по этому в шаблоне есть две ветки исполнения. И именно по этому возникает вопрос про нужность/ненужность финализатора.
Поначалу ты говоришь что он создан для освобождения неуправляемых ресурсов, и большая часть текста делает на этом акцент. Но в конце ты говоришь "по этому и агрегирующие классы должны реализовывать IDis".
Вы пишете: "...либо заблокируете на долгое время файл на файловой шаре, если он был открыт через средства ОС, но не был закрыт. Пример с файловыми шарами особенно хорош, потому что блокировка останется даже после закрытия приложения: открытость файла регулирует та сторона, на которой он находится. А удаленная сторона не получит сигнала закрытия файла, если вы его не закрыли самостоятельно.".
Однако известно, что в Windows при завершении процесса, штатном или нештатном, все незакрытые хэндлы закрываются. Отвечает за это сама операционная система. Работает это через таблицу хэндлов, которая ассоциирована с процессом. Вот что про это пишет Рихтер (http://wm-help.net/books-online/book/59464/59464-22.html): "А вдруг Вы забыли вызвать CloseHandle — будет ли утечка памяти? И да, и нет. Утечка ресурсов (тех же объектов ядра) вполне вероятна, пока процесс еще исполняется. Однако по завершении процесса операционная система гарантированно освобождает все ресурсы, принадлежавшие этому процессу, и в случае объектов ядра действует так: в момент завершения процесса просматривает его таблицу описателей и закрывает любые открытые описатели.". Поскольку в основе .NET процесса все равно лежит нативный процесс, я не вижу причин, почему в .NET должно быть отличное поведение хэндлов.
Здесь я предлагаю вести обсуждение главы. Ошибки, дополнения.
Мне кажется, что тут в принципе стоит заметить, как себя ведёт приложение при различных исключениях:
StackOverflowException — приложение падает в нуль и без кетчей. Чтобы избежать такого — можно чекать стек через RuntimeHelpers.EnsureSufficientExecutionStack
ThreadAbortException — ловится в catch, но пробрасывается выше
OutOfMemoryException — ловится в кетч, если по факту памяти уже достаточно, то приложение продолжает работу
ExecutionEngineException — что-то не так в самом CLR пошло
Подробнее см. Exceptional Exceptions in .NET
Думаю, что называть это некомпетентностью все же не верно. Ведь освобождение ресурсов в «правильном» порядке без повторов по сути ничего не дает. А отсутствие необходимости думать об этом дает довольно много. В 1-ую очередь повышает скорость разработки и надежность.
Предлагаю придерживаться того, что содержание и название заголовков и подзаголовков статей совпадают:
Содержание
Название статьи: вариант # 1
Название статьи: вариант # 2
Отображать можно по-разному, лишь бы было совпадение иерархии и названия в том или в ином виде.
Lingvo для Disposable подсказывает среди прочего вариант: выбрасываемый (после употребления). В русскоязычном IT сленге, наверное, «освобожденный» тут мало подходит. Выброшенный, использованный — не говорят и любого закидают тухлыми яйцами если так кто-то скажет :) Тут скорее уже стоит подбирать по смыслу. Кстати если переводить Dispose() как «прекратить использовать», то невыброс AlreadyDisposedException() — правильно и ставит все на свои места. Но перевод не привычен для нашего языка и «разрушение», как мне кажется, меньшее из зол.
Здесь я предлагаю вести обсуждение главы Исключения. Ошибки, дополнения.
Добрый день. Я бы хотел немного поконтрибьютить в этот проект, но на данный момент меня останавливает отсутствие лицензии. Мне хотелось бы, чтобы мои изменения обладали внятным легальным статусом.
Можете, пожалуйста, определить лицензию на текст?
"Финализатор, в отличии от деструктора, вызовется гарантированно, тогда как деструктор может и не вызваться"
После данной фразы кто-то возможно подумает, что он и правда вызывается абсолютно всегда. Но как вы сами указали (при OutOfMemoryException) вызывается финализатор не всегда. Просто немного противоречат эти 2 фразы. Возможно, стоит как-то по-другому сформулировать. Ну и возможно можно добавить еще 2 случая, когда он не вызывается: при завершении процесса время выполнения финализатора ограничивается примерно 2.2-2.3 секундами(число выясненно имперически, возможно оно в действительности несколько отличается) и вроде суммарное время выполнения всех финализаторов около 40сек, а также когда процесс жестоко убивают(например из TaskManager).
Также возможно Вы посчитаете не лишним добавить как пример к части про события и утечки памяти пример кастомного события, который не страдает данной проблемой
private class CustomDelegateWithWeakReference
{
public WeakReference TargetInstance { get; set; }
public MethodInfo Action { get; set; }
}
Что-то такое, допустим. Возможно, Вы посчитаете, что в этой главе он лишний, но мне сложно это определить.
mayorovp
07.11.17 в 19:35
Кажется, вы забыли упомянуть о еще одном важном достоинстве SafeHandle. Дело в том, что какой-нибудь ThreadAbortException может прилететь после вызова CreateFile — но еще до установки значения поля _handle. Без использования SafeHandle это приведет к редкой но очень неприятной утечке ресурса.
Необходимо прогнать весь текст через ПО ОРФО:
Возможно, этот пример Вас заинтересует.
public class CustomClass
{
public virtual MyClass Field { get; set; }
}
[StructLayout(LayoutKind.Explicit)]
public struct CustomStructLayoutStruct
{
[FieldOffset(0)]
public CustomClass something;
[FieldOffset(0)]
public string str;
}
class Program
{
static void Main(string[] args)
{
CustomStructLayoutStruct customStructLayoutStruct = new CustomStructLayoutStruct();
customStructLayoutStruct.something = new CustomClass();
customStructLayoutStruct.str = "4";
Console.WriteLine($"customStructLayoutStruct.something.GetType(): {customStructLayoutStruct.something.GetType()}");//System.String
Console.WriteLine($"customStructLayoutStruct.something: {customStructLayoutStruct.something}");//4
Console.WriteLine($"customStructLayoutStruct.something.Field: {customStructLayoutStruct.something.Field}");//null
Console.WriteLine($"customStructLayoutStruct.str: {customStructLayoutStruct.str}");//4
}
}
Данное поведение наблюдается лишь при виртуальном свойстве.
В продолжении главы про шаблон Disposable необходимо расписать работу и идеологию шаблона Lifetime
Здесь я предлагаю вести обсуждение главы. Ошибки, дополнения.
"Вызов виртуальных методов хоть и идет через таблицу VMT, но из-за того что индексы заранее известны, то по сути каждый вызов нагружается на единственное разыменовывание указателя. В 99,999% случаев это не повлияет вообще ни на что: проседание (если вообще можно так выразиться) будет настолько маленьким что им в принципе можно принебречь"
По сравнению с невиртуальными методами, проседание все же будет не таким незначительным, т.к. насколько я помню, при вызове невиртуальных методов нет необходимости в разыменовании указателя на таблицу методов, т.к. есть возможность вызвать метод напрямую.
Также виртуальный метод автоматически убирает возможность мощной оптимизации - встаивания метода, что логично, т.к. тип объекта становится известным только во время выполнения.
В секции Раздел вопросов приведен пример реализации IDisposable
интерфейса с последующим примечанием про explicit реализацию и каст.
Предлагаю дополнить этот раздел следующим примером, который, ИМХО, дополняет информацией о expilict реализации и о наследовании интерфейсов:
(Пример на VB
, так как в C#
нет возможности явно переопределить explicit реализацию )
Class Foo
Implements IDisposable
Public Overridable Sub DisposeImp() Implements IDisposable.Dispose
Console.WriteLine("Foo.IDisposable::Dispose")
End Sub
Public Sub Dispose()
Console.WriteLine("Foo::Dispose()")
End Sub
End Class
Class Boo
Inherits Foo
Implements IDisposable
Public Sub DisposeImp() Implements IDisposable.Dispose
Console.WriteLine("Boo.IDisposable::Dispose")
End Sub
Public Shadows Sub Dispose()
Console.WriteLine("Boo::Dispose()")
End Sub
End Class
''' <summary>
''' Неявно реализует интерфейс
''' </summary>
Class Doo
Inherits Foo
''' <summary>
''' Переопределение явной реализации
''' </summary>
Public Overrides Sub DisposeImp()
Console.WriteLine("Doo.IDisposable::Dispose")
End Sub
''' <summary>
''' Неявное перекрытие
''' </summary>
Public Sub Dispose()
Console.WriteLine("Doo::Dispose()")
End Sub
End Class
Sub Main()
Dim foo As New Foo
Dim boo As New Boo
Dim doo As New Doo
CType(foo, IDisposable).Dispose()
foo.Dispose()
CType(boo, IDisposable).Dispose()
boo.Dispose()
CType(doo, IDisposable).Dispose()
doo.Dispose()
End Sub
Здравствуйте! Привожу ссылку на доклад Евгения Пешкова — Особые исключения в .NET:
https://www.youtube.com/watch?v=WLSrYgMWif4
В котором рассматриваются особенности каждого типа исключений, например: StackOverflowException
, ThreadAbortException
, AccessViolationException
и OutOfMemoryException
.
Думаю, имеет смысл упомянуть в книге о данных исключениях и способах их обработки.
связанные союзом "И" части этого предложения не сочетаются, а выделение выглядит небоснованным:
В этой структуре нет никакой информации об обычных методах, полях, свойствах (которые объединяют методы) и никак не связано с рефлексией.
HTH
Здесь я предлагаю вести обсуждение главы. Ошибки, дополнения.
На всех собеседованиях мы же хотели услышать (как мне кажется) от кандидата еще и то, что IDisp прадназначен для а) детерминированного освобождения и, как следствие б) освобождения ресурса на столько быстро, на сколько это возможно
File:
В статье про Disposable вместо FileSafeHandle наверное имелся ввиду SafeFileHandle?
Несмотря на то что неявный boxing - удел C#, а не .NET, стоит рассказать и об этом.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.