2016-12-02 3 views
1

Ich bin von System.Net.HttpClient Klasse abgeleitet, um einen Client zu implementieren, der Tokenabruf und Aktualisierung behandelt. Der Client wird mit allen erforderlichen Authentifizierungsparametern initialisiert und könnte möglicherweise gleichzeitig verwendet werden. In diesem Fall muss ich verhindern, dass der Client mehrere Tokens anfordert (für verschiedene Anfragen).Kann die Verwendung eines Semaphors in asynchronen Methoden zu Deadlocks im WPF-Dispatcher-Thread führen?

Ich bin nicht sicher, ob mein Code zu Deadlocks in einer WPF-Anwendung führen könnte, wenn der Benutzer mehr Web-Anfragen auf dem Dispatcher-Thread startet (weil die Semaphore nichtablaufinvarianten ist, so dass der Dispatcher-Thread könnte blockiert werden während des Wartens auf dem Semaphor, und die ursprüngliche Aufgabe kann möglicherweise nicht abgeschlossen werden, wenn der Dispatcher-Thread blockiert ist).

public class ApiClient : HttpClient 
{ 
    public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     if (_token == null) 
     { 
      await _semaphore.WaitAsync(cancellationToken); 
      try 
      { 
       if (_token == null) 
       { 
        // _token = await _tokenService.AcquireToken(xx,xx,xx); 
       } 
      } 
      finally 
      { 
       _semaphore.Release(); 
      } 
     } 
     else if (_token.IsExpired) 
     { 
      await _semaphore.WaitAsync(cancellationToken); 
      try 
      { 
       if (_token.IsExpired) 
       { 
        // _token = await _tokenService.RefreshToken(xx,xx,xx); 
       } 
      } 
      finally 
      { 
       _semaphore.Release(); 
      } 
     } 
     return await base.SendAsync(request, cancellationToken); 
    } 
} 
+1

Deadlock tritt auf, wenn zwei Threads auf einander warten. Wenn also Ihr Dispatcher-Thread auf den Api-Thread wartet (was tatsächlich passiert) und Api-Thread auf eine Antwort vom Dispatcher-Thread wartet (das sollte nicht der Fall sein), erhalten Sie einen Deadlock. Ich sehe nicht, warum in Ihrem Szenario ein Deadlock auftreten sollte. Der schlimmste Fall wäre ein Timeout, wenn zu viele Anfragen eingehen und einige nicht rechtzeitig fertig werden. – 3615

+0

Aber ich würde definitiv einen Deadlock bekommen, wenn ich die synchrone Wait() Methode des Semaphors verwende, ist das richtig? – Ehssan

+1

Ich glaube nicht. Wenn Sie Wait() anstelle von WaitAsync() verwenden, sollte sich die Situation über Deadlocks nicht ändern, es sei denn, Api Thread würde in verdeckter Weise versuchen, auf den Dispatcher-Thread zuzugreifen. Der Unterschied wäre eine ineffizientere Thread-Verwendung: ApplicationPool Task würde nicht zum Pool zurückkehren, wenn die Semaphore voll ist, aber blockiert werden. Wenn also die nächste Anfrage eintrifft, könnte der blockierte Thread die Anfrage nicht liefern und ein neuer Thread würde erstellt werden. Sie werden also mit viel mehr Threads enden. – 3615

Antwort

0

der Dispatcher-Thread könnte, während auf dem

Diese Semaphore warten blockiert werden kann nicht mit dem Code passieren Sie gezeigt haben. Es verwendet asynchron wartet (await), damit der Thread nicht blockiert wird.

Verwandte Themen