2016-09-01 1 views
0

Ich habe eine Console App (Webjob) in Azure, die eine API auch in azurblau läuft aufgerufen. Die Konsolen-App sendet Nachrichten aus einer CSV-Datei. Wenn ich die Konsolen-App von meinem lokalen (Windows 10) Rechner aus starte (mit api läuft die API), funktioniert es wie erwartet (keine Fehler). Wenn ich die Konsole App in Azure laufen (mit dem api in azur läuft) sind es ca. 980 Nachrichten verarbeitet und dann beginnt die Meldung von Fehlernhttpclient PostAsJsonAsync Fehler nach (n) Nachrichten (Port Erschöpfung?)

Fehler:

  • „Fehler beim Senden der Anforderung“
  • „kann keine Verbindung zum Remote-Server verbinden“

ich glaube, dass aus irgendeinem Grunde, wenn die Konsolenanwendung in Azure ausgeführt wird, die Ports anstrengend, aber ich weiß nicht, wie dieses Problem zu beheben. Meine Datei hat 50.000 Zeilen, aber wie gesagt erreicht nur ca. 980 vor Ausgabe. Am anderen Ende der API posten die empfangenen Nachrichten in einer SQL-Datenbank und einem azurblauen Ereignis-Hub. Wie kann ich erzwingen, dass die Anwendung den Port freigibt, nachdem PostAsJsonAsync abgeschlossen wurde? Wie kann ich überprüfen, ob der Port freigegeben wurde oder wie kann ich überprüfen, ob ein Port verfügbar ist? Wenn Sie aus anderen Gründen wissen, dass ich diese Fehler bekommen könnte, bitte helfen Sie.

Hier ist mein Code:

public async Task<string> PostMessageToAPI(string aMsg) 
{ 
    HttpResponseMessage response = null; 
    string strResponse = "";  
    try 
    { 
     using (var client = new HttpClient()) 
     { 
      client.SetBearerToken("access token here"); 
      client.BaseAddress = new Uri("MyBaseUrl.com"); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      using (response = await client.PostAsJsonAsync("my/url/goes/here", anEvent.ToLower())) 
      { 
       if (response != null) 
       { 
        if (response.StatusCode != HttpStatusCode.OK) 
        { 
         throw new HttpRequestException(response.ReasonPhrase); 
        } 
        else 
        { 
         return await response.Content.ReadAsStringAsync(); 
        } 
       } 
      } 
     } 
    } 
    catch (HttpRequestException ex) 
    {  
     // exception message states: "An error occurred while sending the request" 
    } 
    return strResponse;   
} 
  • Visual Studio 2015 Update 3
  • .net 4.5.1
  • Azure Console App-Plan: Basic 1 kleiner
  • Azure API App-Plan: Basic 1 small
+0

Ist 'PostMessageToAPI' aus einer Multi-Threading-Umgebung genannt? – Stefan

+0

Sie wird von einem Azure-WebJob aus aufgerufen, sodass mehrere Instanzen aufgerufen werden können. Dies wird jedoch von Azure verwaltet. Ich teste jedoch nur eine einzige Instanz. –

+0

Wer/was ist auf dem Remote-Server? Ist es möglich, dass die Verbindungen an diesem Ende nicht ordnungsgemäß getrennt sind? – Stefan

Antwort

-1

Bitte nicht HttpClient wrapp verwenden ed in using. Verwenden Sie eine statische Instanz und teilen Sie sie.

public class MyClass() 
{ 
private HttpClient client = null; 
public MyClass(){ 
    client = new HttpClient(); 
    client.SetBearerToken("access token here"); 
    client.BaseAddress = new Uri("MyBaseUrl.com"); 
    client.DefaultRequestHeaders.Accept.Clear(); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

} 
public async Task<string> PostMessageToAPI(string aMsg) 
{ 
    HttpResponseMessage response = null; 
    string strResponse = "";  
    try 
    { 
     using (var response = await client.PostAsync("my/url/goes/here", new StringContent(aMsg, Encoding.UTF8, "application/json"))) 
     { 
      if (response != null) 
      { 
       if (response.StatusCode != HttpStatusCode.OK) 
       { 
        throw new HttpRequestException(response.ReasonPhrase); 
       } 
       else 
       { 
        return await response.Content.ReadAsStringAsync(); 
       } 
      } 
     } 

    } 
    catch (HttpRequestException ex) 
    {  
     // exception message states: "An error occurred while sending the request" 
    } 
    return strResponse;   
} 
} 

Sie könnten sogar die gleiche Instanz der Klasse teilen, der Punkt ist, ist es nicht optimal, um die Buchse jedes Mal neu zu erstellen und wieder öffnet, wird es schließlich an Buchse Erschöpfung abhängig von Ihrem Anruf Durchsatz führen.

Source

+0

Hinweis: Es gibt nur 9 Methoden [die tatsächlich threadsicher sind] (https: // msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx#Anchor_5) 'CancelPendingRequests',' DeleteAsync', 'GetAsync',' GetByteArrayAsync', 'GetStreamAsync' , 'GetStringAsync',' PostAsync', 'PutAsync' und' SendAsync'. Keine der Eigenschaften ist garantiert threadsicher. Stellen Sie sicher, dass Ihre Erweiterungsmethode "PostAsJsonAsync" keine Methoden verwendet, die nicht in dieser Liste enthalten sind, und keine der Eigenschaften verwendet. –

+0

Guter Fang!Ich habe nur den Code für die statische Nutzung portiert, das ist der Grund für die Port-Erschöpfung. –

+0

Hi Matias, das Problem war, dass ich den httpclient für jeden Anruf neu erstellte. Ich benutze jetzt den gleichen httpclient für alle Anrufe und das Problem ist gelöst. Dies ist im Wesentlichen das, was Sie in Ihrem Code beschrieben haben, also danke. Ich habe Ihre Antwort als Lösung markiert. –

Verwandte Themen