Próbuję napisać kod "Pinging", który będzie publikował do jakiejś usługi odpoczynku raz na minutę.

Moje najprostsze "stare" podejście będzie jak:

while (true)
{
    if (cancellationToken.IsCancellationRequested)
    {
        return;
    }

    await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);

    try
    {
        await PingImpl(clientId, baseUri, cancellationToken);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "ping {BaseUri} {Endpoint} failed", baseUri, Endpoint);
    }
}

Teraz, aby przetestować powtarzające się połączenia na serwerze, zazwyczaj wstrzykiwałbym czas trwania opóźnienia jako milisekundę w produkcji i minutę w produkcji (wiem, że ankieta "wolniejsza" niż raz na minutę z powodu czasu potrzeba Aby wykonać żądanie, jest to akceptowalne)

Teraz, z #Codatime, chciałbym nie bałagać z wtryskiwaniem parametrów i spodziewać się pewnego rozszerzenia na imieniu

   await _clock.Delay(...);

Następnie kod testowy jednostki przesunie fałszywy zegar i uruchom obsługę.

Czy wiesz o elegancki sposób na osiągnięcie takiego zachowania?

0
Max Shlain 18 październik 2020, 15:45

1 odpowiedź

Najlepsza odpowiedź

IClock nie ma żadnego pojęcia opóźniania - tylko tylko odpowiada na pytanie "Co to jest aktualny czas".

Co chcesz, to inna abstrakcja. W projekcie GAX utrzymuję w ramach bibliotek klientów Google Cloud, mamy Ta abstrakcja:

public interface IScheduler
{
    Task Delay(TimeSpan delay, CancellationToken cancellationToken);
}

Tak jak IClock, istnieje wtedy implementacja singleton, która korzysta z Task.Delay - i Wdrożenie testowe, które zaliczają zegar. Powiedziałbym, że implementacja testowa spowodowała nam wiele problemów z czasem, ponieważ jest to naprawdę złożona rzecz do symulacji. Nie możesz po prostu przejść zegara, a następnie zwrócić ukończone zadanie - ponieważ chcesz, aby inne asynchroniczne połączenia występowały w "symulowany czas" między rozpoczęciem a zakończeniem opóźnienia.

Oczywiście możesz mieć prostsze wymagania - jeśli nie masz niczego innego, ty może po prostu bądź w stanie awansować zegar. Ale bądź świadomy ograniczeń tego, pod względem innych operacji asynchronicznych nie dzieje się w międzyczasie.

Podstawowym pomysłem jest to naprawdę przydatne - ale staje się brudny do wdrożenia.

1
Jon Skeet 19 październik 2020, 07:38