Используется ли суффикс "Async" в имени метода зависит от того, используется ли модификатор "async"?

Что такое соглашение для суффикса имени метода с "Async"?

Если суффикс "Async" должен быть добавлен только к методу, объявленному с помощью модификатора async?

public async Task<bool> ConnectAsync()

Или достаточно, чтобы метод просто возвращал Task<T> или Task?

public Task<bool> ConnectAsync()
47
11 апр. '13 в 17:44
источник поделиться
7 ответов

Я думаю, что правда неоднозначна даже из документации Microsoft:

В Visual Studio 2012 и .NET Framework 4.5 любой метод, который, связанное с ключевым словом async (async в Visual Basic), рассматривается как асинхронный метод, а С# и Visual Basic компиляторы выполняют необходимые преобразования для реализации метод асинхронно с использованием TAP. Асинхронный метод должен верните либо объект Task, либо Task<TResult>.

http://msdn.microsoft.com/en-us/library/hh873177 (v = vs .110).aspx

Это уже не так. Любой метод с async является асинхронным, а затем говорит, что он должен возвращать либо Task, либо Task<T> - который не подходит для методов в верхней части стека вызовов, например Button_Click или async void.

Конечно, вы должны рассмотреть, что является пунктом конвенции?

Можно сказать, что соглашение о суффиксе async заключается в том, чтобы сообщить пользователю API, что метод является ожидаемым. Чтобы метод был ожидаемым, он должен возвращать Task для void или Task<T> для метода возврата значения, что означает, что только последний может быть суффикс с async.

Или вы можете сказать, что соглашение суффикса async заключается в том, чтобы сообщить, что метод может немедленно вернуться, отказавшись от текущего потока для выполнения другой работы и потенциально вызывающего расы.

В этой цитате из Microsoft указывается:

По соглашению вы добавляете "Async" к именам методов, которые имеют Асинхронный или асинхронный модификатор.

http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention

Что даже не упоминает о том, что ваши собственные асинхронные методы, возвращающие Task, нуждаются в суффиксе async, который, я думаю, мы все согласны с тем, что они делают.


Таким образом, ответ на этот вопрос может быть следующим: оба. В обоих случаях вам нужно добавить async к методам с ключевым словом async и вернуть Task или Task<T>.


Я попрошу Стивена Туба прояснить ситуацию.

Обновление

Так я и сделал. И вот что наш хороший человек написал:

Если публичный метод является возвратом задачи и является асинхронным по своей природе (как против метода, который, как известно, всегда выполняется синхронно с но по-прежнему возвращает задачу по какой-либо причине), она должна иметь суффикс "Async" . Это руководство. Основная цель здесь именование должно сделать это очень очевидным для потребителя функциональность, вызывающая метод, скорее всего, не будет завершена вся его работа синхронно; это, конечно, также помогает в случае где функциональность подвергается синхронному и асинхронному методы, так что вам нужно различие имен, чтобы их отличить. Как метод достигает своей асинхронной реализации, не имеет значения для именование: используется ли async/await для сбора справки компиляторов, или используются типы и методы из System.Threading.Tasks напрямую (например, TaskCompletionSource) действительно не имеет значения, так как это не влияет на подпись методов в отношении потребителя метод.

Конечно, всегда есть исключения из руководство. Наиболее заметным в случае именования будут случаи где целые типы raison detre должны обеспечивать асинхронную фокусировку функциональность, и в этом случае наличие Async для каждого метода будет избыток, например. методы самой Задачи, которые производят другие Задачи.

Что касается асинхронных методов, возвращающих пустоты, нежелательно иметь тех, кто находится в зоне публичной поверхности, поскольку вызывающий не имеет хорошего способа зная, когда асинхронная работа завершена. Если вы должны разоблачить публичный асинхронный метод, возвращающий пустоту, хотя вы, вероятно, хотите иметь имя, которое передает, что асинхронная работа и вы можете использовать суффикс "Async" здесь, если это имеет смысл. Учитывая, насколько редко этот случай должен быть, Id доказывает, что это действительно в зависимости от конкретного случая.

Я надеюсь, что это поможет, Стив

Краткое руководство от вступительного предложения Стивенса достаточно ясно. Это исключает async void, потому что необычно создавать публичный API с такой конструкцией, поскольку правильный способ реализации асинхронного void состоит в том, чтобы вернуть простой экземпляр Task и позволить компилятору к его магии. Однако, если вам нужен public async void, тогда рекомендуется добавить async. Другие методы top-of-stack async void, такие как обработчики событий, обычно не являются общедоступными и не имеют значения/квалификации.

Для меня это говорит мне, что если я задаюсь вопросом о суффиксе async на async void, я, вероятно, должен превратить его в async Task, чтобы вызывающие могли его ждать, а затем добавить async.

62
08 июля '14 в 11:30
источник

Связанные вопросы


Похожие вопросы

Что такое соглашение для суффикса имени метода с "Async".

Асинхронный шаблон на основе задач (TAP) требует, чтобы методы всегда возвращали Task<T> (или Task) и назывались с суффиксом Async; это не зависит от использования async. И Task<bool> Connect(), и async Task<bool> Connect() будут компилироваться и выполняться просто отлично, но вы не будете соблюдать соглашение об именах TAP.

Если метод содержит модификатор async, или он достаточно, чтобы он просто возвращал задачу?

Если тело метода (независимо от типа или имени возврата) включает await, вы должны использовать async; и компилятор скажет вам: "Оператор" ожидание "может использоваться только в асинхронном методе...". Возврат Task<T> или Task не является достаточным, чтобы избежать использования async. Подробнее см. async (ссылка на С#).

т.е. какая из этих подписей правильная:

Оба async Task<bool> ConnectAsync() и Task<bool> ConnectAsync() должным образом следуют соглашениям TAP. Вы всегда можете использовать ключевое слово async, но вы получите предупреждение о компиляторе "Этот асинхронный метод не использует" ждут "и будет работать синхронно...", если тело не использует await.

18
11 апр. '13 в 17:45
источник

или достаточно, чтобы он просто возвращал задачу?

Это. Ключевое слово async здесь не является реальной проблемой. Если вы реализуете асинхронность без использования ключевого слова async, метод по-прежнему остается "Async", в общем смысле.

9
11 апр. '13 в 17:47
источник

Так как Task и Task<T> оба являются ожидаемыми типами, они представляют собой некоторую асинхронную операцию. Или, по крайней мере, они должны представлять.

Вы должны добавить суффикс Async к методу, который в некоторых случаях (не обязательно все) не возвращает значение, а скорее возвращает обертку вокруг текущей операции. Эта оболочка обычно Task, но в Windows RT она может быть IAsyncInfo. Следите за своим чувством кишки и помните, что если пользователь вашего кода видит функцию Async, он или она будет знать, что вызов этого метода отделен от результата этого метода и что им необходимо действовать соответствующим образом.

Обратите внимание, что существуют такие методы, как Task.Delay и Task.WhenAll, которые возвращают Task и при этом не имеют суффикса Async.

Также обратите внимание, что существуют методы async void, которые представляют собой огонь и забывают асинхронный метод, и вам лучше знать, что метод построен таким образом.

7
11 апр. '13 в 17:54
источник

В Асинхронное программирование с асинхронным и ожидающим (С#), Microsoft предлагает следующее руководство:

Соглашение об именах

По соглашению вы добавляете "Async" к именам методов, которые имеют асинхронный.

Вы можете игнорировать соглашение, в котором событие, базовый класс или интерфейс контракт предлагает другое имя. Например, вы не должны переименовывать общие обработчики событий, такие как Button1_Click.

Я нахожу это руководство неполным и неудовлетворительным. Означает ли это, что в отсутствие модификатора async этот метод следует называть Connect вместо ConnectAsync?

public Task<bool> ConnectAsync()
{
    return ConnectAsyncInternal();
}

Я так не думаю. Как указано в кратком ответе @Servy и тем более подробный ответ от @Luke Puplett, я считаю, что вполне уместно и действительно ожидать, что этот метод должен быть назван ConnectAsync (потому что он возвращает ожидаемый), В дальнейшей поддержке этого @John Skeet в этот ответ в другой вопрос добавляется async к методу имя, независимо от наличия модификатора async.

Наконец, на еще один вопрос, рассмотрите этот комментарий @Damien_The_Unbeliever:

async/await - это детали реализации ваших методов. Это важно не один jot, объявлен ли ваш метод async Task Method() или просто Task Method(), что касается ваших вызывающих абонентов. (В факт, вы можете свободно менять эти два время, не считая его изменением.)

Из этого я делаю вывод, что именно асинхронный характер метода определяет, как его следует назвать. Пользователь метода даже не знает, используется ли модификатор async в его реализации (без исходного кода С# или CIL).

2
26 мая '16 в 19:30
источник

Я бы сказал, что он должен использовать суффикс Async, если он возвращает задачу, независимо от того, объявлен ли метод с помощью модификатора async.

Причина этого в том, что имя объявлено в интерфейсе. Интерфейс объявляет тип возврата, который является Task. Тогда есть два реализации этого интерфейса, одна реализация реализует его с помощью модификатора async, а другая нет.

public interface IFoo
{
    Task FooAsync();
}

public class FooA : IFoo
{
    public Task FooAsync() { /* ... */ }
}

public class FooB : IFoo
{
    public async Task FooAsync() { /* ... */ }
}
1
17 июня '16 в 16:56
источник

Я создаю много API-сервисов и других приложений, которые называют другие системы, где большая часть моего кода работает асинхронно.

Собственное эмпирическое правило, которое я придерживаюсь:

Если есть как неасинхронный, так и асинхронный метод, возвращающий то же самое Я суффикс асинхронный с Async. В противном случае нет.

<сильные > Примеры:

Только один метод:

public async Task<User> GetUser() { [...] }

Тот же метод с двумя сигнатурами:

public User GetUser() { [...] }

public async Task<User> GetUserAsync() { [...] }

Это имеет смысл, поскольку он возвращает те же самые данные, но единственное, что отличается, это способ возврата данных, а не самих данных.

Я также думаю, что эти соглашения об именах существуют из-за необходимости вводить асинхронные методы и по-прежнему поддерживать обратную совместимость.

Я утверждаю, что новый код не должен использовать суффикс Async. Это так же очевидно, как тип возврата String или Int, как упоминалось ранее в этом потоке.

1
14 дек. '17 в 13:19
источник

Посмотрите другие вопросы по меткам или Задайте вопрос