Сообщение Re[11]: [.NET][async][WinForms] от 22.12.2016 10:19
Изменено 22.12.2016 10:20 Serginio1
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Sinix, Вы писали:
S>>Здравствуйте, Serginio1, Вы писали:
S>>>>Первое правило любого предложения в стиле "а давайте сделаем так": посмотри на последствия.
S>>> Я как раз и смотрю и вижу косяки.
S>>Не вопрос, какие именно косяки?
S> Да постоянные вопросы из-за дедлоков
S>>> Большинство клиентского кода как раз потому, что сделали ConfigureAwait(true) по умолчанию и никто не знает про существование ConfigureAwait. И весь интернет усыпан вопросами о дедлоках.
S>>А можно пример? Есть такое подозрение, что проблема там не в ConfigureAwait(), а в исчерпании потоков, доступных для запуска продолжений. Так это и с ConfigureAwait(false) можно устроить, дурное дело нехитрое
S> Так я тебе в твоем примере и привел, когда при вызове RunAsync внутри ты будешь не будешь использовать ConfigureAwait(false)
S>Просто ты не читаешь.
S>
S> Мало того ты же минус мне влепил за http://ru.stackoverflow.com/questions/512968/win10-universal-app-async-%d0%b7%d0%b0%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d0%b0/513241#513241
S>
S>>>При этом не везде в клиентском коде нужно переключатся на поток контекста.
S>>По умолчанию — везде. Если, конечно, не хочется ловить баги типа "опс, культура не та" в самом неожиданном месте.
S> Вот именно. Но это бывает не всегда. А народ про ().ConfigureAwait(false); вообще не знает
S>>> При этом в ошибки установки свойств контрола в не потоке GUI можно возвращать ошибку про использовании ConfigureAwait, а с дедлоком вообще ничего не выдается.
S>>Не вопрос, давай с всё тем же кодом из примера выше. Есть идеи, как заставить его выдавать ошибку стандартными средствами фреймворка? Не ломая совместимости.
S>>Напоминаю, исключение по факту бросается в фоновом потоке.
S> Не ломая совместимости можно для библиотек сделать опцию для компилятора или проекта ConfigureAwait(false) по умолчанию.
S>>И после этого — как быть с ошибками, не связанными с обращением к UI?
S> А все также и остается. Но проблема дедлоков и лишней писанины убирается.
S>>> Правлю.
S>>Спасиб
Все посыпаю голову пеплом! Что то я совсем заработался. Проблема с Result.
Я в 1С не могу вызвать await поэтому мне приходится вызывать Result, а он как раз и ведет к дедлоку.
У всех прошу прощения и удаляюсь в монастырь.
Но вот сделать опцию для ConfigureAwait(false); стоит
S>Здравствуйте, Sinix, Вы писали:
S>>Здравствуйте, Serginio1, Вы писали:
S>>>>Первое правило любого предложения в стиле "а давайте сделаем так": посмотри на последствия.
S>>> Я как раз и смотрю и вижу косяки.
S>>Не вопрос, какие именно косяки?
S> Да постоянные вопросы из-за дедлоков
S>>> Большинство клиентского кода как раз потому, что сделали ConfigureAwait(true) по умолчанию и никто не знает про существование ConfigureAwait. И весь интернет усыпан вопросами о дедлоках.
S>>А можно пример? Есть такое подозрение, что проблема там не в ConfigureAwait(), а в исчерпании потоков, доступных для запуска продолжений. Так это и с ConfigureAwait(false) можно устроить, дурное дело нехитрое
S> Так я тебе в твоем примере и привел, когда при вызове RunAsync внутри ты будешь не будешь использовать ConfigureAwait(false)
S>Просто ты не читаешь.
S>
S>private async Task Button_Click(object sender, RoutedEventArgs e)
S> {
S> await RunAsync().ConfigureAwait(true); //1
S> button.Content = "x_X";
S> MessageBox.Show("Completed:" + t.IsCompleted));
S> }
S>private async Task RunAsync()
S> {
S> await Task.Delay(1); //2 Получим классический дедлок
S>// Так как await Task.Delay(1); возвращается в поток GUI но, await RunAsync() его ждет
S> }
S>
S> Мало того ты же минус мне влепил за http://ru.stackoverflow.com/questions/512968/win10-universal-app-async-%d0%b7%d0%b0%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d0%b0/513241#513241
S>
Клик по кнопке здесь приводит к дедлоку. UI поток стартует новый I/O поток на строке «2» и уходит в спящий режим на строке «1», ожидая завершения работы. После того как I/O поток заканчивает выполнение, оставшаяся часть метода RunAsync передается на выполнение вызывающему (UI) потоку. Но тот в это время находится в спящем режиме, ожидая завершения метода. Дедлок.
S>>>При этом не везде в клиентском коде нужно переключатся на поток контекста.
S>>По умолчанию — везде. Если, конечно, не хочется ловить баги типа "опс, культура не та" в самом неожиданном месте.
S> Вот именно. Но это бывает не всегда. А народ про ().ConfigureAwait(false); вообще не знает
S>>> При этом в ошибки установки свойств контрола в не потоке GUI можно возвращать ошибку про использовании ConfigureAwait, а с дедлоком вообще ничего не выдается.
S>>Не вопрос, давай с всё тем же кодом из примера выше. Есть идеи, как заставить его выдавать ошибку стандартными средствами фреймворка? Не ломая совместимости.
S>>Напоминаю, исключение по факту бросается в фоновом потоке.
S> Не ломая совместимости можно для библиотек сделать опцию для компилятора или проекта ConfigureAwait(false) по умолчанию.
S>>И после этого — как быть с ошибками, не связанными с обращением к UI?
S> А все также и остается. Но проблема дедлоков и лишней писанины убирается.
S>>> Правлю.
S>>Спасиб
Все посыпаю голову пеплом! Что то я совсем заработался. Проблема с Result.
Я в 1С не могу вызвать await поэтому мне приходится вызывать Result, а он как раз и ведет к дедлоку.
У всех прошу прощения и удаляюсь в монастырь.
Но вот сделать опцию для ConfigureAwait(false); стоит
Все посыпаю голову пеплом! Что то я совсем заработался. Проблема с Result.
Я в 1С не могу вызвать await поэтому мне приходится вызывать Result, а он как раз и ведет к дедлоку.
У всех прошу прощения и удаляюсь в монастырь.
Но вот сделать опцию для ConfigureAwait(false); стоит
Я в 1С не могу вызвать await поэтому мне приходится вызывать Result, а он как раз и ведет к дедлоку.
У всех прошу прощения и удаляюсь в монастырь.
Но вот сделать опцию для ConfigureAwait(false); стоит