@CSharpChatЭта группа больше не существует

Страница 1265 из 1888
Vinc
18.06.2017
08:43:34
отлично, спасибо)

Летучая
18.06.2017
09:21:08
await Task.Run(() => DoStuff().Result); await Task.Run(async () => await DoStuff()); Господа, какой вариант производительнее использовать? Чот неоч понимаю, в каком потоке будет выполняться await DoStuff(), вызванный в таком контексте. Будет ли вообще профит от Task.Run, если ещё и в него что-то асинхронное запихнуть?

Friedrich
18.06.2017
09:22:11
А чо не просто await DoStuff()?

Летучая
18.06.2017
09:23:34
Ну он там запрос шлёт, десериализует оч жирный жсон и обарабатывает полученные списки. Хочется распараллелить, шобы побыстрее

Google
Friedrich
18.06.2017
09:23:42
Если выбирать между этими двумя, то мне кажется, что второй будет лучше. В первом ты занимаешь тред у тредпула, и блокируешь его на результате какой-то асинхронной операции. А во втором ты занимаешь тред из тредпула, стартуешь DoStuff() (которая может в другом треде выполняться или хз где), и освобождаешь этот тред.

Летучая
18.06.2017
09:27:57
А будет ли в таком случае разница между await DoStuff(); и Task.Run(async () => await DoStuff());? Или в этом кейсе от обёртки с таск.ран вообще нет толку?

Andrey
18.06.2017
09:28:23
Нет толку

Летучая
18.06.2017
09:28:27
В обоих случаях скедулер же DoStuff в отдельный поток засунет, в который решит

Летучая
18.06.2017
09:29:27
Да, я помню. Но там был вопрос про возвращение другого Task из метода Task. А здесь именно Task<T> внутри войда, который что-то возвращает и войд что-то делает с этим.

Владимир
18.06.2017
09:30:06
Ой, ну не пофиг ли?
вопрос был про производительность, поэтому нет, не пофиг

Friedrich
18.06.2017
09:30:21
Владимир
18.06.2017
09:31:42
Ну он там запрос шлёт, десериализует оч жирный жсон и обарабатывает полученные списки. Хочется распараллелить, шобы побыстрее
все равно не особо понял, что ты сделать хочешь, покажи код? Распараллеить можно и просто создав 3 таска и сделав Task.WhenAll

Friedrich
18.06.2017
09:39:20
Тут разница в том, на каком треде будет запущена синхронная часть асинхронного метода.

Google
Friedrich
18.06.2017
09:39:51
Как известно, эта синхронная часть запускается всегда на текущем треде.

Ну так вот, в варианте с await Task.Run(async () => await AsyncTestMethod()); весь метод будет запущен в другом потоке, включая его синхронную часть (до первого await). А в варианте с await AsyncTestMethod() синхронная часть, как и положено, выполняется в текущем треде.

Поэтому в моём примере весь Method2 выполняется в одном потоке, а Method1 сразу возвращает управление, и продолжает выполнение в другом треде.

Летучая
18.06.2017
09:44:47
Супер, спасибо! То есть при обычном await мы получаем таск, который ломится в главный тред, а при Task.Run скедулер выбирает другой тред и происходит распараллеливание в классическом понимании этого слова. Правильно понимаю?

Friedrich
18.06.2017
09:45:21
Разница только в том, в каком треде будет выполняться начало таска.

Но у некоторых тасков это "начало" может быть довольно длинным, и ты его захочешь отгрузить в отдельный тред.

Летучая
18.06.2017
09:48:03
Получается, Task.Run больше годится для тяжёлой синхронной работы в отдельном треде?

Andrey
18.06.2017
09:48:51
Да.

Летучая
18.06.2017
09:49:48
✋️?

Владимир
18.06.2017
09:51:43
Разница только в том, в каком треде будет выполняться начало таска.
у меня метод два в одном треде вообще выполняется



это потому что в AsyncTestMethod нет эвейтов?

Но, вообще, интересно, не знал, что без эвейта/вызова Wait он вообще заходит в метод.

Friedrich
18.06.2017
09:54:49
у меня метод два в одном треде вообще выполняется
Да, у меня тоже, я же там привёл аутпут. В этом и был поинт, ты всё правильно понял :)

Владимир
18.06.2017
09:57:36
Task.Run возвращает *уже запущенную* задачу.
Не, это я знаю, я про уровень выше var m1Result = Method1(); я видимо сильно ошибался, когда думал, что асинхронные методы запускаются только по вызову await/Wait на них.

Я думал, что такая строка должна вернуть незапущенный таст.

Denis
18.06.2017
10:00:12
Но..

Google
Denis
18.06.2017
10:00:28
Сильно ошибался

Летучая
18.06.2017
10:13:26
Starting method1 from 1 1: Starting async task on thread 1 Method1 started, proceeding in 1 Task initiated on thread 3 Task finished on thread 3 1: Async task finished on thread 3 Starting method2 from 1 Всё равно не понимаю, растолкуйте пожалуйста. Таск инициирован в потоке 3, выполнен и закончен тоже в потоке 3. Более того, окончание Method1 тоже происходит в потоке 3. Так значит Task.Run всё-таки перекидывает свои эвейты в другие потоки, отличные от главного? private static async Task AsyncTestMethod() { Console.WriteLine($"Task initiated on thread {Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(10000); Console.WriteLine($"Task finished on thread {Thread.CurrentThread.ManagedThreadId}"); } private static async Task Method1() { Console.WriteLine($"1: Starting async task on thread {Thread.CurrentThread.ManagedThreadId}"); await Task.Run(async () => await AsyncTestMethod()); Console.WriteLine($"1: Async task finished on thread {Thread.CurrentThread.ManagedThreadId}"); }

Откуда берётся вывод о том, что await в Task.Run уходит из его потока?

Ilya
18.06.2017
10:17:07
я что то провтыкал или где код для этого вывода?

Владимир
18.06.2017
10:17:21
Смотрите все: https://gist.github.com/ForNeVeR/503028bbc4dd7975b2e86a49fa87c77e

Friedrich
18.06.2017
10:20:13
Опыт на UI-контексте ещё надо будет провести, наверное.

Я думаю, что там будет работать примерно так же (т.е. любой код в Task.Run будет запущен в другом потоке).

Ilya
18.06.2017
10:21:02
но вкратце работает так: Method1 - вызывает TestMethod на потоке пула потокв (№3) из за того, что тут нет synchronizatrion context продолжение метода выполняется в том же потоке ( Async task finished №3)

а в Method2 там вообще никакого переключения потоков нет, потому что тут всё выполняется в 1 одном потоке, т.к тут нет асинхронности или многопточности

Friedrich
18.06.2017
10:25:34
не до конца понятно, что автор хотел сказать
Автор хотел наглядно продемонстрировать разницу между await AsyncTestMethod() vs await Task.Run(async () => await AsyncTestMethod()) :)

Friedrich
18.06.2017
10:25:56
Ну, по крайней мере попытался это сделать.

Владимир
18.06.2017
10:26:32
Я тоже поигрался, таки да, метод два вообще полностью синхронно выполняется.

Ilya
18.06.2017
10:27:08
Автор хотел наглядно продемонстрировать разницу между await AsyncTestMethod() vs await Task.Run(async () => await AsyncTestMethod()) :)
я бы сказал, что второй вариант использовать надо только в крайних случаях, потому что такое использование - признак поворота не туда

Friedrich
18.06.2017
10:27:17
Согласен.

Летучая
18.06.2017
10:48:30
Чот всплыл ещё вопрос по сборщику мусора. Если имеется вот такой код: public DerivedClass : BaseClass { public DerivedClass() => base.SomeEvent += OnSomethingHappened; <...> } То следует ли реализовывать IDisposable и в Dispose отвязывать хэндлер? base.SomeEvent -= OnSomethingHappened; На StackOverflow пишут, что если не отвязать, GC не соберёт этот объект, потому что хэндлер будет на него ссылаться. Так ли это на самом деле? Так ли это, если хендлер находится внутри самого класса?

Anatoly
18.06.2017
10:49:19
Если ты не отписываешся то могут быть проблемы.

Если внутри самого класса, то я думаю норм должно быть. По сути циклическая зависимость же, которую GC должен раздуплить.

Я реализую IDisposable и там отписываю всех кого могу. Не так уж и много кода займёт

Google
Friedrich
18.06.2017
10:52:38
Тогда нет проблемы.

Утечка при подписке на события действительно имеет место, но она происходит только тогда, когда источник события живёт дольше подписчика. Если ты подписываешься на свои собственные события или на события объектов, которые живут меньше тебя, тогда всё в порядке.

Представь, что ты генерируешь кучу каких-нибудь маложивущих объектов (кнопок каких-нибудь), которые подписываются на событие Close долгоживушей формы. Без отписки все эти кнопки будут продолжать висеть в памяти только для того, чтобы форма вызвала у них у всех обработчик события Close, когда будет закрываться. Даже если эти кнопки давно уже удалены с экрана и больше ни для чего не нужны.

Летучая
18.06.2017
10:56:55
Спасибо за объяснения! Получается, вот в такой реализации https://gist.github.com/Worldbeater/7daeca6e56e3db593eb16468ee0a21f3 Dispose не обязателен?

Friedrich
18.06.2017
10:58:08
Если там под капотом классическое событие — тогда нет, не обязательно отписываться.

Летучая
18.06.2017
10:58:57
Пожалуй, лучше на всякий случай отпишусь. Мало ли что они там накрутили.

Admin
ERROR: S client not available

Friedrich
18.06.2017
10:59:28
А вот с подпиской на DependencyProperty изредка бывает смехота. Я точно ловил утечки из-за этого, и мне приходилось даже от своих собственных событий отписываться однажды.

Пожалуй, лучше на всякий случай отпишусь. Мало ли что они там накрутили.
Я бы не стал костылировать, а, чтоб наверняка, проверил бы профайлером или залогировал вызов финализатора, чтобы проверить, что всё ок.

Egor
18.06.2017
11:02:48
>Я бы не стал костылировать это не форневер!

Friedrich
18.06.2017
11:03:34
>Я бы не стал костылировать это не форневер!
Который предлагает вместо того, чтобы оставить небольшой костылёк, развернуть полноценное исследование с профайлером и финализаторами — тот Форневер!

>Я бы не стал костылировать это не форневер!
А ты вот нам, кстати, как раз и расскажи про утечки с DependencyProperty. Такое бывает или я гоню?

Egor
18.06.2017
11:04:32
бывает конечно

посему четкие посоны пишут без байндингов в кодбехайнде!

Летучая
18.06.2017
11:05:51
?

Blue Screen of Death
18.06.2017
11:08:54
Так и знал, что все эти ваши mvvm не нужны

Владимир
18.06.2017
11:09:38
кодбехайнд это не про мввм

Ilya
18.06.2017
11:30:08
Google
P O W E R
18.06.2017
11:35:21
Ребята подскажите как можно исправить ошибку, нужно что бы я мог использовать одну кавычку типа string y = " " ";

Дмитрий
18.06.2017
11:35:46
ларчик всегда открывается просто

обычно это решается виртуальными методами
бывает, что базовый класс не предоставляет методы вида protected virtual void OnSomeEvent() { ... } или такие методы могут быть приватными в таких случаях и приходится подписываться на событие

Летучая
18.06.2017
12:49:10
зачем подписываться на эвенты базового класса?
нету доступа к базовому классу просто

Ilya
18.06.2017
12:50:15
нету доступа к базовому классу просто
А виртуальные методы есть?

Летучая
18.06.2017
12:54:41
Ого! И правда есть. Спасибо!

Влад
18.06.2017
13:37:46
А что чаще бывает в вакансиях С#: MySQL или MS SQL Server?

Andrey
18.06.2017
13:38:30
EF

Gid
18.06.2017
13:39:01
Майскл это когда ты видишь то что нужно переписать

в основном

или пхп

Ilya
18.06.2017
13:39:30
какой самый быстрый способ вставить много данных в sqllite?

Igor
18.06.2017
13:45:02
А с MongoDB сейчас в .NET работа есть?

Andrey
18.06.2017
13:45:24
Есть

Gid
18.06.2017
13:46:44
Вообще с чем захочешь с тем и будет

Страница 1265 из 1888

Эта группа больше не существует Эта группа больше не существует