2017-05-09 8 views
5

Ich habe etwas Code geschrieben, um einige Daten mit Dapper in SQL Server zu schreiben. Ich muss nicht warten, bis dieser Schreibvorgang abgeschlossen ist, bevor ich mit der anderen Arbeit fortfahre, daher möchte ich Task.Run() verwenden, um diese asynchron zu machen.C#, Dapper, SQL Server und Verbindungspooling

Ich habe (mit) Erklärungen für diese mein System im Rest Aufruf:

using (IDataAccess ida = new DAL()) 
     { 
      ida.WriteMessageToDB(id, routingKey, msgBody); 
     } 

Meine DAL die dbConnection.State automatisch überprüfen, wenn die Anweisung using ran ist, und eine einfache Lösung versuchen, wenn es geschlossen. Dies funktioniert problemlos für alle Nicht-Async-/TPL-Auswahlaufrufe.

Wenn ich jedoch eine Last von Schreibvorgängen gleichzeitig warf, fiel der Task.Run() - Code um, als die Verbindung für einige von ihnen geschlossen wurde - im Wesentlichen denke ich, dass die Parallelität des Codes den Zustand bedeutete wurde von anderen Aufgaben geschlossen.

Ich 'behoben' dies durch eine Überprüfung, um den Connection.State innerhalb der Task.Run() - Code zu öffnen, und dies scheint das Problem "gelöst" zu haben. Wie so:

Task.Run(() => 
      { 
       if (dbConnection.State == ConnectionState.Closed) 
       { 
        dbConnection.Open(); 
       } 

       if (dbConnection.State == ConnectionState.Open) 
       { 
        *Dapper SQL String and Execute Commands* 
       } 
      }); 

Als ich SELECT * FROM sys.dm_exec_connections von SSMS danach laufen, sehe ich viel mehr Verbindungen. Zu erwarten?

Jetzt wie ich es verstehe:

  • Dapper befasst sich nicht mit Verbindungspooling
  • SQL Server automatisch mit Connection Pooling umgehen?

Ist etwas falsch mit dieser Lösung? Oder ein besserer Weg? Ich würde das Verbindungspooling aus offensichtlichen Gründen und so schmerzlos wie möglich verwenden.

Vielen Dank im Voraus.

+5

Zunächst wird Dapper die Verbindung öffnen, wenn es nicht bereits geöffnet ist. Zweitens verwendet Dapper nur ADO.Net, das Verbindungen aus dem Verbindungspool verwendet. Schließlich verfügt Dapper über asynchrone Methoden, die Sie anstelle von 'Task.Run' verwenden könnten. – juharr

Antwort

1

Dank Juharr - ich habe Ihre Antwort upvoted.

Für Bezug auf anderen, änderte ich Funktion schreiben, zu warten und Dapper async:

private async Task WriteMessageToDB(Guid id, string tableName, string jsonString) 
    { 
      string sql = *Redacted* 
      await dbConnection.ExecuteScalarAsync<int>(sql, new { ID = id, Body = jsonString }); 
    } 

und erstellt dann eine neue Aufgabe in den Anrufern, die das Ergebnis überwacht.

Diese arbeitet konsequent unter Last und nicht übermäßig neue Verbindungen zu sehen, entweder geschaffen.

Verwandte Themen