При таком количестве транзисторов неудивительно, что современные процессоры x86 испещрены недокументированными инструкциями и аппаратными уязвимостями.
Три простых совета чтобы не знать проблем с асинхронным программированием.
1) Забудьте про .Wait() и .Result как про страшный сон. Если вы программируете асинхронно они вам не нужны.
2) Забудьте про ConfigureAwait. Это костыль и мусор который захламляет код и не пригодится при выполнении пункта 1
3) Не хотите чтобы UI тормозил? прекратите работаь в потоке UI по умолчанию и вызывать асинхронные методы только когда возникает проблема. И забудьте про контексты, это мусор на который не стоит полагаться. Работайте в потоке без контекста, возвращаясь в поток UI через Dispatcher.Invoke, только тогда когда это действительно нужно.
Команда WPF сделала кучу запутанных перегрузок Dispatcher.Invoke, но вместо них сгодятся вот такие не очень красивые зато рабочие и удобные екстеншены.
public static class DispatcherExtensions
{
async public static Task InvokeAsyncTask(this Dispatcher dispatcher, Action act) =>
await dispatcher.InvokeAsync(act);
public static class DispatcherObjectExtensions
{
public static Task Invoke(this DispatcherObject obj, Action act) =>
obj.Dispatcher.InvokeAsyncTask(act);
public static Task Invoke(this DispatcherObject obj, Func act) =>
obj.Dispatcher.InvokeAsyncTask(act);
public static Task Invoke(this DispatcherObject obj, Func act) =>
obj.Dispatcher.InvokeAsyncTask(act);
Проблема только в криворукости разработчиков и их опыте.
Знать бы где упасть, да соломки бы подстелить. Узнать о своей криворукости зачастую получается уже собрав все грабли.
Плохо, когда фреймворк подталкивает к использованию плохих практик (это я про инжекцию куда-либо кроме конструктора), и хорошо когда выходят статьи которые поднимают этот вопрос.
Все рекомендации в программировании в основном и состоят из того как делать не стоит.
Как стоит делать в каждом конкретном случае описать невозможно.
Мне повезло познакомится с Simple Injector в качестве первого контейнера, рекомендую почитать основные принципы (англ.). Идеальное руководство чтобы правильно понять контейнеры.
У обычного таска был оверхед при синхронном выполнении, в какой-то версии большого .net это пофиксили., а в Core сразу было хорошо., а ValueTask появился для случая когда асинхронный метод чаще выполняется синохронно чем асинхронно.
Большое спасибо за грамотную статью про Span., очень хорошо и понятно пишете!
Всегда слежу за новыми фичами c# и изучаю все по мере выхода. Когда появился Span, было сложно сходу понять что он делает, а времени эксперементировать самому как всегда нет) Прочитал много статей, но только после этой все понял и вопрос можно считать закрытым.
есть пару вопросов
1) пока читал статью ожидал упоминания ArraySegment и так его и не встретил. Видел использование этого класса в системных апи с сокетом, а в .net Core 1.x только они и были доступны — хотелось бы раскрытия вопроса, решает-ли Span проблемы которые решал ArraySegment, и что теперь использовать.
2) Поправьте меня если не прав — машина тьюринга описывает программирование на стеке, и куча не является необходимым элементом для создания тьюринг полных языков/программ, она существует чтобы было удобно строить абстракции. Глобальный вопрос состоит в том, возможно-ли использовать силу абстракции ООП и при этом остаться полностью на стеке, ну или хотя бы в той мере, чтобы куча не так сильно влияла на производительность. Самому пока чего-то не хватает чтобы разобраться.
как живется без кнопок page up / page down и home / end на одной клавише?
на всех новых асусах клавиатура теперь кастрирована на 3 кнопки, поэтому никак не решусь обновиться))
Плохо настаиваете. Надо сдавать в ремонт по кд. Есть сроки по закону, там не отвертишься. Качество техники сильно упало, лично я сдаю 80% обратно в магазин. Не надо этого стесняться, вы имеете право.
здесь наверное было «использовать композицию вместо наследования»
1-(1-0.0307)^5 = 0.14436003026
не очень похоже на 41,64%
Звучит весьма противоречиво
1) Забудьте про .Wait() и .Result как про страшный сон. Если вы программируете асинхронно они вам не нужны.
2) Забудьте про ConfigureAwait. Это костыль и мусор который захламляет код и не пригодится при выполнении пункта 1
3) Не хотите чтобы UI тормозил? прекратите работаь в потоке UI по умолчанию и вызывать асинхронные методы только когда возникает проблема. И забудьте про контексты, это мусор на который не стоит полагаться. Работайте в потоке без контекста, возвращаясь в поток UI через Dispatcher.Invoke, только тогда когда это действительно нужно.
Команда WPF сделала кучу запутанных перегрузок Dispatcher.Invoke, но вместо них сгодятся вот такие не очень красивые зато рабочие и удобные екстеншены.
public static class DispatcherExtensions
{
async public static Task InvokeAsyncTask(this Dispatcher dispatcher, Action act) =>
await dispatcher.InvokeAsync(act);
async public static Task InvokeAsyncTask(this Dispatcher dispatcher, Func act) =>
await dispatcher.InvokeAsync(act);
async public static Task InvokeAsyncTask(this Dispatcher dispatcher, Func act) =>
await await dispatcher.InvokeAsync(act);
async public static Task InvokeAsyncTask(this Dispatcher dispatcher, Func<Task> act) =>
await await dispatcher.InvokeAsync(act);
}
А можно еще вот так
public static class DispatcherObjectExtensions
{
public static Task Invoke(this DispatcherObject obj, Action act) =>
obj.Dispatcher.InvokeAsyncTask(act);
public static Task Invoke(this DispatcherObject obj, Func act) =>
obj.Dispatcher.InvokeAsyncTask(act);
public static Task Invoke(this DispatcherObject obj, Func act) =>
obj.Dispatcher.InvokeAsyncTask(act);
public static Task Invoke(this DispatcherObject obj, Func<Task> act) =>
obj.Dispatcher.InvokeAsyncTask(act);
}
Знать бы где упасть, да соломки бы подстелить. Узнать о своей криворукости зачастую получается уже собрав все грабли.
Плохо, когда фреймворк подталкивает к использованию плохих практик (это я про инжекцию куда-либо кроме конструктора), и хорошо когда выходят статьи которые поднимают этот вопрос.
Как стоит делать в каждом конкретном случае описать невозможно.
Мне повезло познакомится с Simple Injector в качестве первого контейнера, рекомендую почитать основные принципы (англ.). Идеальное руководство чтобы правильно понять контейнеры.
Design Principles
Design Decisions
Кстати он еще и внутри адекватно сделан и поэтому быстро работает (advanced)
Simple Injector Pipeline
ps: не спешите переводить проект на юнити на Simple Injector, он использует кодогенерацию и не заведется под iOS
Всегда слежу за новыми фичами c# и изучаю все по мере выхода. Когда появился Span, было сложно сходу понять что он делает, а времени эксперементировать самому как всегда нет) Прочитал много статей, но только после этой все понял и вопрос можно считать закрытым.
есть пару вопросов
1) пока читал статью ожидал упоминания ArraySegment и так его и не встретил. Видел использование этого класса в системных апи с сокетом, а в .net Core 1.x только они и были доступны — хотелось бы раскрытия вопроса, решает-ли Span проблемы которые решал ArraySegment, и что теперь использовать.
2) Поправьте меня если не прав — машина тьюринга описывает программирование на стеке, и куча не является необходимым элементом для создания тьюринг полных языков/программ, она существует чтобы было удобно строить абстракции. Глобальный вопрос состоит в том, возможно-ли использовать силу абстракции ООП и при этом остаться полностью на стеке, ну или хотя бы в той мере, чтобы куча не так сильно влияла на производительность. Самому пока чего-то не хватает чтобы разобраться.
на всех новых асусах клавиатура теперь кастрирована на 3 кнопки, поэтому никак не решусь обновиться))