Что-то вроде следующего должно начать:
<?php
function sortDate($a, $b) {
return strtotime($a['date']) - strtotime($b['date']);
}
$input = array('info' => array(array('id' => 2, 'date' => '2019-04-11'), array('id' => 1, 'date' => '2010-05-15')));
usort($input['info'], 'sortDate');
print_r($input);
Создайте SynchronizationContext
, который выдает исключение в реализации Post
и Send. В качестве альтернативы, он может установить логическое значение, указывающее, были ли вызваны Send
или Post
, что позволит вам проверить это логическое значение позже (если вы сделаете это, вы, вероятно, захотите запустить предоставленный делегат, иначе вы могли бы рискнуть тупиковую ситуацию).
Установите экземпляр этого пользовательского контекста синхронизации в качестве текущего контекста синхронизации в начале теста, когда тестируете метод, который никогда не должен использовать текущий контекст синхронизации.
Цель состоит в том, чтобы отсеять неправильное использование ConfigureAwait в очень большой кодовой базе.
blockquote>Некоторые команды выбирают для этого инструмент анализа кода. Есть несколько доступных. Наиболее распространенный подход, который я видел, состоит в том, чтобы потребовать a
ConfigureAwait
для каждогоawait
и явно указать либоtrue
, либоfalse
. Это гарантирует, что каждыйawait
был рассмотрен и поток контекста явно. Другие команды применяют специфичные для проекта правила «всегда использоватьConfigureAwait(false)
» и просто зависят от проверки кода для проектов, которые не могут следовать этому правилу.Проблема с вашим примером кода состоит в том, что невозможно для
DoWhatever
узнать, был ли он вызван косвенно, из-заTask.Run
. Если вы переписываете эти методы, это становится ясным:public static async Task CapturesContext() { var task = Task.Run(() => DoWhatever()); await task; } public static async Task DoesNotCaptureContext() { var task = Task.Run(() => DoWhatever()); var configuredTask = task.ConfigureAwait(false); await configuredTask; }
Первые строки переписанных методов должны прояснить, что
DoWhatever
не имеет представления, захватят лиCapturesContext
илиDoesNotCaptureContext
контекст или не. Обратите внимание на «волю» (будущее время) - вполне возможно, чтоDoWhatever
выполняется и заканчивает выполнение до того, какConfigureAwait(false)
даже будет вызван.Теперь вы можете проверить изнутри задачи, выполняется ли она в контексте прямо сейчас . Но в этом случае для обоих примеров методов
DoWhatever
не увидят контекст из-заTask.Run
. Так что это не поможет вам обнаружить тот факт, чтоCapturesContext
действительно захватывает контекст;DoWhatever
не видит контекст, поэтому не может его обнаружить.Пользовательский
SynchronizationContext
является хорошим решением для модульных тестов, но его было бы неудобно использовать во время выполнения, так как у вас есть некоторые методы, которым нужен контекст. По этой причине большинство команд предпочитают полагаться на проверку кода и / или инструменты анализа кода.