2017-07-09 1 views
-2

Ich habe eine Azure WebApp (C#/MVC), die ich versuche, einen CosmosDb-Tabellenspeicher zu integrieren. Ich habe das nugget-Paket für "WindowsAzure.Storage-PremiumTable" hinzugefügt und den folgenden Code hinzugefügt, um auf eine Tabelle zuzugreifen und sie zu erstellen, falls sie noch nicht existiert.CosmosDb-Tabellenspeicherfunktionen kehren nie zurück

string connectionString = "DefaultEndpointsProtocol=https;AccountName=[myAccountName];AccountKey=[myAccountKey];TableEndpoint=https://[myAccountName].documents.azure.com"; 
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); 
CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
var table = tableClient.GetTableReference("people"); 
table.CreateIfNotExists(); 

Ich trat durch diesen Code und alles ist in Ordnung, bis es zu CreateIfNotExists kam. Wenn ich diese Funktion überspringe, kehrt sie nie zurück. Ich ließ es über eine Stunde sitzen und es kam nie zurück. Ich habe es ohne den Debugger versucht und es kam immer noch nicht zurück. Ich habe auch versucht, um diesen Codeblock herum Try/Catch-Logik hinzuzufügen, aber es wurden keine Ausnahmen ausgelöst.

Ich ging dann auf die CosmosDb-Website und Gab die Beispielanwendung für diese Operation und führte es nur Ändern der Connectionstring, um meine Kontoinformationen zu haben, und es hat gut funktioniert. Ich habe den obigen Code in die main() - Funktion der Beispiel-App kopiert/eingefügt und er hat trotzdem funktioniert.

Das führte mich zu der Annahme, dass es etwas mit einer schlechten Interaktion mit etwas zu tun hat, das in meiner WebApp vorhanden ist.

Ich kopierte das obige Code-Snippet in die Application_Start-Methode in der Global.asax, so dass es ausgeführt würde, bevor viele andere Dinge ins Spiel kommen, und überraschenderweise hat es funktioniert.

Ich habe dann den Code in eine Controller-Aktion verschoben und diese Aktion ausgelöst (in diesem Fall habe die Site dem Benutzer die Anmeldeseite angezeigt), und der CreateIfNotExists-Aufruf kann nicht erneut ausgeführt werden.

Nur um einige zusätzliche Dinge, die ich versuchte, ich habe auch die CreateIfNotExists mit einer Anfrage für eine Zeile aus der People-Tabelle ersetzt (die existiert und die Zeile ist im DataExplorer auf der Azure-Management-Portal sichtbar). Dies weist jedoch auch auf dasselbe Problem hin wie das Aufrufen von CreateIfNotExists, das niemals von dem Aufruf zurückkommt.

Also entschied ich mich als Nächstes, den Rest meiner WebApp aus dem Bild zu entfernen, also erstellte ich eine brandneue MVC WebApp in VS2017, fügte das "WindowsAzure.Storage-PremiumTable" nugget-Paket hinzu (v 0.1.0- Vorschau), dann aktualisiert alle Pakete auf die aktuellste (mit Ausnahme von Microsoft.Azure.DocumentDB seit das PremiumTable-Paket derzeit nur mit v 1.14.0 von DocumentDb kompatibel ist). Ich habe das obige Code-Snippet in die Index-Methode des Home-Controllers eingefügt und die App im Debugger gestartet. Erneut gab CreateIfNotExists nicht zurück.

Das führt mich zu der Annahme, dass einige Inkompatibilität zwischen ASP.NET MVC-Anwendungen und das WindowsAzure.Storage-PremiumTable-nugget-Paket besteht.

Um diese Theorie weiter zu testen, erstellte ich eine brandneue Konsolenanwendung (.Net Framework), fügte das PremiumTables nuget-Paket hinzu, fügte das obige Code-Snippet in die main() -Methode ein und die CreateIfNotExists kam in ungefähr 1 Sekunde zurück wie normal.

Ich wollte das nur für den Fall veröffentlichen, dass jemand anderes das Problem hat. Außerdem hoffe ich, die entsprechende Aufmerksamkeit der internen Microsoft-Entwickler zu bekommen, um das herauszufinden, da das PremiumTable-Paket nicht opensource ist, also konnte ich nicht hineintreten, um zu versuchen, das Problem weiter zu diagnostizieren.

[UPDATE] wie Camillo darauf hingewiesen hat, kann es Probleme bei der Verwendung der synchronen API-Aufrufe in ASP.NET-Anwendungen geben. Wenn Sie also zu den asynchronen Versionen des Anrufs wechseln, wird das Problem gemildert.

+0

Bitte fügen Sie die Methodensignatur und wie Sie diese Methode aufrufen, wenn es nicht zurück. Ich bin zu 99% sicher, dass Sie entweder einen Deadlock oder einen Kontextwechsel bekommen. Übrigens, es gibt keine ASP.NET-Inkompatibilität mit CosmosDB. Ich erstelle gerade eine Anwendung gegen CosmosDB –

+0

Ich stellte das vollständige Codeausschnitt in der Post zur Verfügung. Die einzige Sache, die geändert werden muss, sind die Connectionstring-Kontoinformationen. Wie Sie aus dem Code-Snippet bemerken werden, rufe ich table.CreateIfNotExists ohne Parameter auf. – user3459730

+1

Nein, Sie haben mir nicht zur Verfügung gestellt, was ich angefordert habe. Ohne die Methodensignatur (public void DoSomething ....) und wie Sie es nennen (x.DoSomething ...) können wir nicht wissen, wo das Problem liegt –

Antwort

0

Wie in der Frage kommentiert, ist das Problem ein Deadlock höchstwahrscheinlich durch einen Kontextwechsel verursacht.

Um das zu verhindern, müssen Sie dies ändern:

public IActionResult Hello() 
{ 
    string connectionString = "something here"; 
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); 
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
    var table = tableClient.GetTableReference("people"); 
    table.CreateIfNotExists(); 
} 

Dazu:

public async Task<IActionResult> Hello() 
{ 
    string connectionString = "something here"; 
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); 
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
    var table = tableClient.GetTableReference("people"); 
    await table.CreateIfNotExistsAsync(); 
} 
Verwandte Themen