Intereting Posts
Windows Forms: прохождение кликов через частично прозрачное окно «всегда сверху» Отмена блокировки вызова AcceptTcpClient Захват события выхода приложения – WinForms Использование Moq, Как настроить вызов метода с входным параметром в качестве объекта с ожидаемыми значениями свойств? динамически выбирать между двумя метками для отображаемого имени в mvc ef Как цветные пиксели, которые не являются черными в растровом изображении желтым цветом, используя LockBits? Дублирование с использованием директив в нескольких файлах Консольное приложение не закрывается Список C # – Удаление элементов во время цикла / итерации WinForms ComboBox SelectedIndexChanged не срабатывает при наборе нескольких символов, за которыми следуют Alt + Down Получить правильные собственные символы .net для Windbg Являются ли назначение ссылок и чтение атомными операциями? Как распространять ошибки и исключения, возникающие при привязке данных WPF? Возврат пользовательского объекта из структуры Entity и назначение объекту Data Data Source как публиковать произвольный json-объект для webapi

Параметр по умолчанию для CancellationToken

У меня есть asynchronous код, который я хотел бы добавить в CancellationToken. Тем не менее, существует множество реализаций, где это не требуется, поэтому я хотел бы иметь параметр по умолчанию – возможно, CancellationToken.None. Тем не мение,

Task DoStuff(...., CancellationToken ct = null) 

доходность

Значение типа ” не может использоваться в качестве параметра по умолчанию, потому что нет стандартных преобразований для типа «System.Threading.CancellationToken»

а также

 Task DoStuff(...., CancellationToken ct = CancellationToken.None) 

Значение параметра по умолчанию для ‘ct’ должно быть константой времени компиляции

Есть ли способ получить значение по умолчанию для CancellationToken?

    Оказывается, следующие работы:

     Task DoStuff(...., CancellationToken ct = default(CancellationToken)) 

    который, согласно документации , интерпретируется так же, как CancellationToken.None :

    Вы также можете использовать оператор C # default(CancellationToken) для создания пустого маркера отмены.

    Есть ли способ получить значение по умолчанию для CancellationToken?

    К сожалению, это невозможно, так как CancellationToken.None не является постоянной времени компиляции, что является обязательным для значений по умолчанию в необязательных аргументах.

    Однако вы можете обеспечить тот же эффект, сделав перегруженный метод вместо того, чтобы пытаться использовать параметры по умолчанию:

     Task DoStuff(...., CancellationToken ct) { //... } Task DoStuff(....) { return DoStuff(...., CancellationToken.None); } 

    Другой вариант – использовать параметр Nullable , по умолчанию он имеет значение null и обрабатывать его внутри метода:

     Task DoStuff(...., CancellationToken? ct = null) { var token = ct ?? CancellationToken.None; ... } 

    Вот несколько решений в порядке убывания общей доброты:

    1. По default(CancellationToken) используется значение по умолчанию:

     Task DoAsync(CancellationToken ct = default(CancellationToken)) { … } 

    Семантически, CancellationToken.None был бы идеальным кандидатом для дефолта, но не может использоваться как таковой, потому что он не является константой времени компиляции. default(CancellationToken) – это следующая лучшая вещь, потому что это постоянная времени компиляции и официально документирована как эквивалентная CancellationToken.None .

    2. Предоставление метода перегрузки без параметра CancellationToken :

    Или, если вы предпочитаете перегрузки метода по необязательным параметрам (см. Этот и этот вопрос по этой теме):

     Task DoAsync(CancellationToken ct) { … } // actual method always requires a token Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token 

    Для методов интерфейса то же самое можно достичь с помощью методов расширения:

     interface IFoo { Task DoAsync(CancellationToken ct); } static class Foo { public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None); } 

    Это приводит к более тонкому интерфейсу и избавляет разработчиков от явной записи перегрузки метода пересылки.

    3. Сделать параметр null и использовать значение null качестве значения по умолчанию:

     Task DoAsync(…, CancellationToken? ct = null) { … ct ?? CancellationToken.None … } 

    Мне нравится это решение наименее, потому что типы с нулевым значением имеют небольшую служебную нагрузку, а ссылки на токен отмены становятся более подробными из-за оператора нулевой коалесценции ?? ,

    Ответ Тофутима – один из способов, но из комментариев я вижу, что у людей проблемы с ним.

    В этом случае я предположил, что можно иметь метод следующим образом:

     Task DoStuff(...., CancellationToken ct) { } 

    и перегрузить его как:

     Task DoStuff(....) { return DoStuff(...., CancellationToken.None); } 

    Это компилируется, потому что значение CancellationToken.None не требуется во время компиляции.