Wie man so asynchron? (async, await in C#, MVC)
Ich habe gerade versucht, einen Teil meiner ASP .NET MVC-Anwendung asynchron-aber auch nach der Lektüre und der Versuch, eine Menge, die ich nicht wirklich verstehen, die async-await-Muster und hoffe, jemand könnte mir einen Tip geben.
Grundsätzlich habe ich die folgenden:
-
Einen javascript-Aufruf an mein controller holt sich eine teilweise Ansicht für ein Diagramm (das passiert mehrmals nach dem laden der Seite für eine Menge von Diagrammen)
//Load content of one chart my.loadChartContent = function (data, callback) { $.post("/Dashboard/GetChartContent/", data, function (datain) { if (isFunction(callback)) callback(datain); }); };
-
Einer controller-action, die fordert, eine Datenbank-Methode in einer anderen Klasse
public ActionResult GetChartContent(int id, bool isDraft = false) { //do something //... var chartdata = _dataService.GetDataForChart(chart, isDraft, _user.Id); //long running query //do something with chartdata return View(chartdata); }
-
Die Daten-Klasse (_dataService), die holt sich die Daten aus der Datenbank mit einem SqlDataReader-und lädt ein DataTable mit Daten.
Das problem ist, dass obwohl der Code asynchron ausgeführt, die Controller-Aktionen zu sein scheint, blockiert, bis ein Ergebnis aus der DataService-Klasse gibt. Beginnen möchte ich alle Abfragen in der Datenbank und warten auf die Ergebnisse asynchron, so dass lange andauernde Abfragen nicht blockieren kürzeren. (In SQL Server Profiler sehe ich die Abfragen als Beginn-Ende Beginn-Ende Beginn-Ende => jedoch sollte es beginnen-beginnen-Anfang - Ende-Ende-Ende)
Wo soll ich verwenden async-await? Ist es genug, um es (irgendwie) für meine controller-action oder ist es notwendig, um die ganze "call-Kette" asynchron?
Update:
Wenn ich SQLConnection.OpenAsync und ExecuteReaderAsync der code wird nie abgeschlossen...und ich weiß nicht, warum?
public async Task<Query> GetSqlServerData(Query query)
{
var dt = new DataTable();
var con = new SqlConnection(query.ConnectionString);
await con.OpenAsync();
var cmd = new SqlCommand(query.SelectStatement, con);
var datareader = await cmd.ExecuteReaderAsync();
dt.Load(datareader);
con.Close();
query.Result = dt;
return query;
}
Der code ist nur ein basic cmd.ExecuteReader() und DataTable.Load(reader), die füllt eine datatable. Es ist nicht ein sql problem .
Sollten Sie die asynchrone version der Methoden (
BeginExecuteReader
und ReadAsync
im SqlDataReader
) blogs.microsoft.co.il/blogs/bnaya/Archiv/2012/01/15/...Überprüfen Sie die Antworten hier: stackoverflow.com/questions/13131776/...
Leider habe ich es nicht bekommen. Bitte siehe mein update oben.
InformationsquelleAutor Jetro223 | 2013-10-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Danke Euch allen für Eure Antworten. Aber die wahre Antwort ist viel einfacher, als ich dachte. Stephen wies mich in die richtige Richtung mit dem Satz
Wusste ich, und im Allgemeinen, stimmt aber offensichtlich nicht, wenn man mit sessions, weil ASP.NET MVC auf jede Anfrage (von einem Benutzer) abgeschlossen, um die Synchronisierung der Sitzung. Finden Sie eine bessere Erklärung hier: http://www.stefanprodan.eu/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/
So - nur die Dekoration meiner controller mit ...
...Tat es und jetzt habe ich das Ergebnis das ich wollte - gleichzeitige Abfragen auf meinem SQL-Server und eine viel schnellere Reaktionszeit.
@Stephen - es ist mehr als 2 gleichzeitige Anfragen => http://www.browserscope.org/?category=network
InformationsquelleAutor Jetro223
Der Begriff "asynchronous" angewendet werden können, gibt es verschiedene Möglichkeiten. In JavaScript ist alles asynchron. Alle HTTP-Aufrufe sind natürlich asynchron.
Wenn Sie nicht sehen alle sql überlappen, dann sollten Sie sicher sein, dass Sie anrufen
loadChartContent
mehrere Male (nicht aufrufen es einmal zu einer Zeit, angekettet durch Rückrufe oder ähnliches). Der browser beschränken Sie sich auf zwei gleichzeitige Anforderungen, aber Sie sollten sehen, zwei Anforderungen gleichzeitig schlagen Sie Ihre sql server.Machen Sie Ihren server-Seite
async
wird dir nicht helfen, weilasync
nicht ändern, dass das HTTP-Protokoll (da beschreibe ich auf meinem blog). Auch wenn du deine Datenbank zugreifenasync
Ihre controller-Aktion wird noch zu warten, bis Sie abgeschlossen ist, und der browser wird noch begrenzen Sie an zwei herausragende Anforderungen. Server-side -async
ist nützlich für die Skalierung Ihrer web-Servern, aber wenn Ihr web-server sprechen, auf einen einzigen SQL Server-back-End, dann gibt es keinen Punkt in der Skalierung Ihrer web-server, weil Ihr web-server ist nicht der entscheidende Faktor in Ihrer Skalierbarkeit.On a side note, ich vermute der Grund, Ihre
async
- code wird nie abgeschlossen ist, weil man mitErgebnis
oderWait
; ich führe dies auf mein blog.So, zurück zu deinem ursprünglichen problem: wenn Sie anfangen wollen alle die Abfragen an die Datenbank, dann werden Sie sich ändern müssen-API "klobige" statt "gesprächig". I. e., hinzufügen eines
GetChartContents
Aktion dauert mehrere ids und führt alle Abfragen parallel. Ich würde empfehlen, mitasync
Datenbank Methoden mit so etwas wie dies:InformationsquelleAutor Stephen Cleary
Ich denke, dieses tutorial bietet einen guten Ausgangspunkt für das, was Sie zu tun versuchen.
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
InformationsquelleAutor akrobet
Wenn Sie haben:
Dann verwenden:
InformationsquelleAutor Ahmed KRAIEM