0
votes

Comment appeler la méthode Async dans un fil mais attendez-le en C #

J'ai un thread chargé d'appeler un webapi à partir de 4 sites Web exactement toutes les 2 secondes. La méthode d'appel WebAPI ne doit pas être attendue car si un site Web n'est pas disponible, il attendra 5 seconde pour obtenir le délai d'attente, puis le prochain appel de site Web sera retardé. Comme httpClient in .NET 4.7.2 n'a que des méthodes asynchronisées, il doit être utilisé avec attendre et, le cas échéant, le compilateur donne un avertissement et nous pouvons obtenir un comportement inattendu (comme le dit Microsoft). Devrais-je utiliser Tâche.Run ou appelez WHInpool.QueueUserSerWorkItem pour faire un appel WebAPI en parallèle. Voici SUDOCODE:

public class Test1
{
        private AutoResetEvent waitEvent = new AutoResetEvent(false);
        private volatile bool _terminated = false;

        public void Start()
        {
            Thread T = new Thread(ProcThread);
            T.Start();
        }

        private async void ProcThread()
        {
            while (!_terminated)
            {
                await CallWebApi();    <=========== this line 
                waitEvent.WaitOne(2000);
            }

        }

        private async Task CallWebApi()
        {
            HttpClient client = new HttpClient();
            .....
            .....
        }

 }


4 commentaires

Vous n'avez pas besoin de attendre si vous n'êtes pas attendu de résultat de retour de celui-ci (ou) n'a aucune opération dépendante


Évitez ASYNC VOID . Son but est spécifiquement de rendre les gestionnaires d'événements asynchrones possibles. Vous n'avez pas de gestionnaire d'événements ici, vous avez le délégué à exécuter par le fichier .


En tant que note latérale, httpclient est destiné à être instancié une fois et réutilisé tout au long de la vie d'une application. Instancitation d'une classe httpClient pour chaque demande d'épuiser le nombre de sockets disponibles sous des charges lourdes. ( source )


Et si le site Web échoue à plusieurs reprises pour répondre à la manière dont vous gérerez toutes les demandes tirées toutes les 2 à partir du marécage du système? On dirait que vous devez étrangler la boucle des 2s pour tout site Web qui échoue?


3 Réponses :


-1
votes

quelque chose comme ça. BTW Prenez ceci comme pseudo code que je tape assis assis sur mon lit :) xxx


0 commentaires

0
votes

Si tout ce que vous voulez, c'est exécuter une méthode toutes les deux secondes, alors un System.Timers.Timer code> est probablement l'outil le plus approprié à utiliser:

public class Test1
{
    private readonly HttpClient _client;
    private readonly System.Timers.Timer _timer;

    public Test1()
    {
        _client = new HttpClient();
        _timer = new System.Timers.Timer();
        _timer.Interval = 2000;
        _timer.Elapsed += Timer_Elapsed;
    }

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        var fireAndForgetTask = CallWebApiAsync();
    }

    private async Task CallWebApiAsync()
    {
        var html = await _client.GetStringAsync("http://example.com");
        //...
    }

    public void Start() => _timer.Start();
    public void Stop() => _timer.Stop();
}


0 commentaires

2
votes

Vous avez donc une procédure ASYNC qui utilise un httpclient pour récupérer des informations et traiter les données récupérées: xxx pré>

amélioration 1 strong>: c'est une bonne pratique pour suffixer ASYNC Méthodes avec Async. Ceci est fait pour permettre à une version ASYNC exister à côté d'une version non asynchreuse qui fait quelque chose de même. P>

à l'intérieur de cette méthode que vous utilisez l'une des méthodes httpClient pour récupérer les informations. Comme CallwebapiaSync est attendable, je suppose que les méthodes Async sont utilisées (GetASync, GetStreamasync, etc.), et que la méthode n'attend que lorsque cela nécessite le résultat de la méthode ASYNC. P>

La bonne chose à ce sujet est, C'est comme un utilisateur de CallwebapiaSync, tant que vous n'attendez pas l'appel, vous êtes libre de faire d'autres choses, même si le site Web n'est pas réagi. Le problème est: après 2 secondes, vous souhaitez appeler la méthode à nouveau. Mais que faire si la méthode n'a pas encore fini. P>

amélioration 2 forte> Parce que vous souhaitez pouvoir démarrer une nouvelle tâche, alors que le précédent n'a pas fini: Les tâches ont commencé et les jeter lorsque vous avez terminé. P>

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
Test1 test = new Test1();

Task taskCallWebApiRepeatedly = test.StartAsync(cancellationTokenSource.Token);

// because you didn't await, you are free to do other things, while WebApi is called
// every 2 seconds
DoSomethingElse();

// you get bored. Request cancellation:
cancellationTokenSource.Cancel();

// of course you need to await until all tasks are finished:
await Task.Wait(taskCallWebApiRepeatedly);


0 commentaires