async плохо?
От: vaa  
Дата: 22.07.22 09:16
Оценка:
почему можно написать так:
 async Task Do() {}

, но компайлер будет ругаться
и нельзя так:
Task Do() {}
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: async плохо?
От: Sharov Россия  
Дата: 22.07.22 09:51
Оценка: :)
Здравствуйте, vaa, Вы писали:

vaa>почему можно написать так:

vaa>
vaa> async Task Do() {}
vaa>

vaa>, но компайлер будет ругаться
vaa>и нельзя так:
vaa>
vaa>Task Do() {}
vaa>


Во втором случае метод должен вернуть Task, поэтому правильно не компилируется. Почему компилируется первый метод-- без понятия. Ну т.е., видимо, в первом методе не обязательно что-либо возвращать.
Кодом людям нужно помогать!
Re[2]: async плохо?
От: ksg71 Германия  
Дата: 22.07.22 10:14
Оценка: 12 (1)
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, vaa, Вы писали:


vaa>>почему можно написать так:

vaa>>
vaa>> async Task Do() {}
vaa>>

vaa>>, но компайлер будет ругаться
vaa>>и нельзя так:
vaa>>
vaa>>Task Do() {}
vaa>>


S>Во втором случае метод должен вернуть Task, поэтому правильно не компилируется. Почему компилируется первый метод-- без понятия. Ну т.е., видимо, в первом методе не обязательно что-либо возвращать.


в первом компилятор сам вставит код который таск вернет
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re: async плохо?
От: Ночной Смотрящий Россия  
Дата: 22.07.22 10:49
Оценка: +1
Здравствуйте, vaa, Вы писали:

vaa>почему можно написать так:

vaa>
vaa> async Task Do() {}
vaa>

vaa>, но компайлер будет ругаться
vaa>и нельзя так:
vaa>
vaa>Task Do() {}
vaa>


Потому что такова логика работы async. Почему у тебя такой вопрос возникает?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: async плохо?
От: vaa  
Дата: 22.07.22 12:31
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, vaa, Вы писали:


vaa>>почему можно написать так:

vaa>>
vaa>> async Task Do() {}
vaa>>

vaa>>, но компайлер будет ругаться
vaa>>и нельзя так:
vaa>>
vaa>>Task Do() {}
vaa>>


НС>Потому что такова логика работы async. Почему у тебя такой вопрос возникает?

потому что странная логика, у меня в голове не укладывается. или пусть хотя бы компайлер не ругается.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: async плохо?
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.22 13:33
Оценка: 9 (1) +3
Здравствуйте, vaa, Вы писали:
vaa>потому что странная логика, у меня в голове не укладывается.
Вам нужно разобраться с асинком. То, что он не укладывается в голове — это недостаток подготовки.
vaa>или пусть хотя бы компайлер не ругается.
Компайлер говорит вам о том, что ваш метод — очень подозрительный. Он претендует на асинхронность, но ничего асинхронного не делает.
Зачем вам нужен такой метод?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: async плохо?
От: Ночной Смотрящий Россия  
Дата: 22.07.22 13:36
Оценка:
Здравствуйте, vaa, Вы писали:

НС>>Потому что такова логика работы async. Почему у тебя такой вопрос возникает?

vaa>потому что странная логика, у меня в голове не укладывается. или пусть хотя бы компайлер не ругается.

Логика абсолютно тривиальная. А компайлер ругается, потому что код с практической точки зрения бесполезен. Вырожденные случаи не могут быть основанием для специальных исключений из правил, ибо бесполезно усложняют спецификацию и компилятор.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: async плохо?
От: Ночной Смотрящий Россия  
Дата: 22.07.22 13:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Компайлер говорит вам о том, что ваш метод — очень подозрительный. Он претендует на асинхронность, но ничего асинхронного не делает.

S>Зачем вам нужен такой метод?

Кейс то можно придумать.
public interface IFoo
{
  Task Do();
}

class Foo : IFoo
{
  async Task Do() => await DoCore();
}

class FooMock : IFoo
{
  async Task Do() => _logger.LogInfo("Do called"); // Oops!
}


Другое дело что добавлять для таких ситуаций отдельное правило не очень разумно.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: async плохо?
От: Александр Кузнецов Россия  
Дата: 22.07.22 15:20
Оценка: 6 (1) +2
Здравствуйте, vaa, Вы писали:

vaa>почему можно написать так:

vaa>
vaa> async Task Do() {}
vaa>

vaa>, но компайлер будет ругаться
vaa>и нельзя так:
vaa>
vaa>Task Do() {}
vaa>



Асинхронный метод должен возвращать какую-либо Task, выполнение которой потом будут ждать в await. Причём сам механизм асинхронности работает хитро — таска создаётся и возвращается автоматически, по сути, до выполнения метода, а сам метод потом работает как обычный (ему пофиг, что он завёрнут в Task). По сути, твой первый метод — это обычный void метод, у которого не обязательно писать return.
"Идеально правильно" его было бы записать вот так:
async Task<void> Do() {}
Но void не используется в generic, и поэтому пишут просто Task, чтобы не было ошибок компиляции. Ругается в нём компилятор на то, что внутри асинхронного метода нет await и сразу предупреждает, что, фактически, метод будет выполняться синхронно, не смотря на все асинки.

А второй метод — это обычный (не асинхронный) метод, который возвращает Task. Никакой обёртки над методом нет, ты просто должен вернуть какой-либо Task и, соответственно, компилятор ожидает return этой таски.
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
Re: async плохо?
От: ltc  
Дата: 22.07.22 16:16
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>почему можно написать так:

vaa>
vaa> async Task Do() {}
vaa>

vaa>, но компайлер будет ругаться
vaa>и нельзя так:
vaa>
vaa>Task Do() {}
vaa>


Почему сразу плохо-то?

Вот так нельзя
Task Do() {}

ровно по той же причине, почему нельзя вот так
int Do() {}

всё логично.

А вот это на самом деле генерирует некоторое количество кода, включая конечный автомат, и возвращает таску, в которую "завёрнут" результат выполнения метода (в данном случае void).
async Task Do() {}
Re[5]: async плохо?
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.22 17:26
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Sinclair, Вы писали:


S>>Компайлер говорит вам о том, что ваш метод — очень подозрительный. Он претендует на асинхронность, но ничего асинхронного не делает.

S>>Зачем вам нужен такой метод?

НС>Кейс то можно придумать.

НС>
НС>public interface IFoo
НС>{
НС>  Task Do();
НС>}

НС>class Foo : IFoo
НС>{
НС>  async Task Do() => await DoCore();
НС>}

НС>class FooMock : IFoo
НС>{
НС>  async Task Do() => _logger.LogInfo("Do called"); // Oops!
НС>}
НС>

Непонятно.
public interface IFoo
{
  Task Do();
}

class Foo : IFoo
{
  // async Task Do() => await DoCore(); // а зачем тут async и await? 
  Task Do() => DoCore(); // тот же результат, только без лишней task, которая ждёт task.
}

class FooMock : IFoo
{
  Task Do() {_logger.LogInfo("Do called"); return Task.CompletedTask}; // Fine!
}
class FooMock : IFoo
{
  async Task Do() { await _logger.LogInfo("Do called")}  // Fine!
}


НС>Другое дело что добавлять для таких ситуаций отдельное правило не очень разумно.

+1
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: async плохо?
От: Ночной Смотрящий Россия  
Дата: 22.07.22 19:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S> Task Do() => DoCore(); // тот же результат, только без лишней task, которая ждёт task.


Там может и сложнее логика быть, не из одной строчки. Это же схематический пример.

S> Task Do() {_logger.LogInfo("Do called"); return Task.CompletedTask}; // Fine!


Больше писанины.

S> async Task Do() { await _logger.LogInfo("Do called")} // Fine!


LogInfo синхронный, его нельзя await.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: async плохо?
От: Sharov Россия  
Дата: 22.07.22 21:17
Оценка:
Здравствуйте, ksg71, Вы писали:

S>>Во втором случае метод должен вернуть Task, поэтому правильно не компилируется. Почему компилируется первый метод-- без понятия. Ну т.е., видимо, в первом методе не обязательно что-либо возвращать.

K>в первом компилятор сам вставит код который таск вернет

Ага, вот такая штука будет скомпилирована:
[CompilerGenerated]
    private sealed class <Do>d__1 : IAsyncStateMachine
    {
        public int <>1__state;

        public AsyncTaskMethodBuilder <>t__builder;

        public C <>4__this;

        private void MoveNext()
        {
            int num = <>1__state;
            try
            {
            }
            catch (Exception exception)
            {
                <>1__state = -2;
                <>t__builder.SetException(exception);
                return;
            }
            <>1__state = -2;
            <>t__builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            //ILSpy generated this explicit interface implementation from .override directive in MoveNext
            this.MoveNext();
        }

        [DebuggerHidden]
        private void SetStateMachine(IAsyncStateMachine stateMachine)
        {
        }

        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
            this.SetStateMachine(stateMachine);
        }
    }

   

    [AsyncStateMachine(typeof(<Do>d__1))]
    [DebuggerStepThrough]
    private Task Do()
    {
        <Do>d__1 stateMachine = new <Do>d__1();
        stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
        stateMachine.<>4__this = this;
        stateMachine.<>1__state = -1;
        stateMachine.<>t__builder.Start(ref stateMachine);
        return stateMachine.<>t__builder.Task;
    }
Кодом людям нужно помогать!
Re[2]: async плохо?
От: vaa  
Дата: 23.07.22 01:06
Оценка:
Здравствуйте, ltc, Вы писали:

ltc>
ltc>async Task Do() {}
ltc>


неужели вы не видите, что это нарушает ранее созданные правила?
есть возвращаемый тип, но ничего не возвращаем. такс слово лишнее.
async Do() {}

было бы намного логичнее в этом случае.
void же нас не удивляет.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[7]: async плохо?
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.22 02:16
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Там может и сложнее логика быть, не из одной строчки. Это же схематический пример.
Ок, я просто думал речь о делегировании во что-то
S>> async Task Do() { await _logger.LogInfo("Do called")} // Fine!
НС>LogInfo синхронный, его нельзя await.
Тогда только первый вариант, да.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: async плохо?
От: xpalex  
Дата: 25.07.22 09:23
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>есть возвращаемый тип, но ничего не возвращаем. такс слово лишнее.

vaa>
vaa>async Do() {}
vaa>

vaa>было бы намного логичнее в этом случае.
vaa>void же нас не удивляет.

Если вы пришли из функционального языка, то сигнатура функции это первое что на что нужно обращать внимание.
Потому что именно знание сигнатуры функции позволяет их комбинировать.

async вообще ортогонален сигнатуре. это больше про сахар, который разрешит вам использовать await конструкции в теле функции и позволит записать стейт-машину в процедурном стиле.

Есть у меня несколько знакомых "новичков" в программировании, вот там тенденция, что все методы имеют типа void -> void, а весь стейт находится в полях объекта/структуры.
Т.е. для них функция/метод это просто "именнованный" кусок кода.
И да, для них "очевидно" что если тип не указан, то это должен быть void. Это ж самый распрострененный тип возврата.
Отсылка к функциональным языкам обычно что-то меняет в головах.

Но я в первый раз вижу что бы пришедший из функционального языка говорил, что пропуск типа в сигнатуре это нормально.
Re[3]: async плохо?
От: ltc  
Дата: 25.07.22 14:21
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>неужели вы не видите, что это нарушает ранее созданные правила?

vaa>есть возвращаемый тип, но ничего не возвращаем. такс слово лишнее.

async Task<int> Do() { return 5; }


А вот такое несоответствие не смущает? Обещали Task<int>, возвращаем просто int.

vaa>
vaa>async Do() {}
vaa>

vaa>было бы намного логичнее в этом случае.
vaa>void же нас не удивляет.

Но ведь на самом деле метод вернет именно таску и без использования await её мы и получим. А такая сигнатура будет только еще более нелогичной.
Исходно проблема в возможности вызвать метод с await или без него, что, по сути, меняет тип возвращаемого результата. Идеально в данном случае не сделать, кмк.
Re[3]: async плохо?
От: karbofos42 Россия  
Дата: 26.07.22 20:50
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>неужели вы не видите, что это нарушает ранее созданные правила?

vaa>есть возвращаемый тип, но ничего не возвращаем. такс слово лишнее.

async/await — синтаксический сахар со своими нюансами.
Тут уже придётся принять их или не использовать.

Наличие/отсутствие async не меняет сигнатуру метода.
Было бы не менее странно, если бы для реализации интерфейса:
interface IA
{
  Task Do();
}


был написан такой класс:
class A: IA
{
  async Do() {}
}


и непонятно что потом делать с таким классом:
class A2: IA
{
  async Do() {}
  Task Do() { ... }
}


в итоге бы началось такое безудержное веселье, если бы они решили не нарушать "ранее созданные правила"...
Re[4]: async плохо?
От: vaa  
Дата: 27.07.22 13:52
Оценка:
Здравствуйте, karbofos42, Вы писали:



K>в итоге бы началось такое безудержное веселье, если бы они решили не нарушать "ранее созданные правила"...


А это как понимать:

async IAsyncEnumerable<T> List() {await Task.Yield(); yield return  default(T);};
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: async плохо?
От: karbofos42 Россия  
Дата: 28.07.22 14:21
Оценка: +1
Здравствуйте, vaa, Вы писали:

vaa>А это как понимать:


Что разработчики языка мало думают и лепят что попало
Re: async плохо?
От: Caracrist https://1pwd.org/
Дата: 31.08.22 14:11
Оценка:
Здравствуйте, vaa,

Синхронный:
Task Do() {}

Соответствует асинхронному:
async Task<Task> Do() {}

И он тоже не скомпилируется...

А вот асинхронный:
async Task Do() {}

Соответствует синхронному:
void Do() {}

И они оба одинаково законно компилируются.
~~~~~
~lol~~
~~~ Single Password Solution
Отредактировано 31.08.2022 14:13 Caracrist . Предыдущая версия . Еще …
Отредактировано 31.08.2022 14:13 Caracrist . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.