diff --git a/bsmd.database/DBManager.cs b/bsmd.database/DBManager.cs index 735cf5cf..1deaf673 100644 --- a/bsmd.database/DBManager.cs +++ b/bsmd.database/DBManager.cs @@ -15,6 +15,8 @@ using System.Diagnostics; using Newtonsoft.Json; using log4net; using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Threading; namespace bsmd.database { @@ -32,6 +34,7 @@ namespace bsmd.database private bool _closeConnectionAfterUse = false; private readonly List truncatedFieldCollection = new List(); private Dictionary messageHistoryTypeDict; + private SemaphoreSlim _asyncSemaphore = new SemaphoreSlim(1); #endregion @@ -99,6 +102,22 @@ namespace bsmd.database } } + public async Task ConnectAsync(string dbConnectionString) + { + try + { + _con = new SqlConnection(dbConnectionString); + await _con.OpenAsync(); + this.ConnectionString = dbConnectionString; + return true; + } + catch(Exception ex) + { + _log.ErrorFormat("DBManager cannot connect:{0}", ex.Message); + return false; + } + } + public void Disconnect() { if (this._con?.State == ConnectionState.Open) @@ -785,6 +804,13 @@ namespace bsmd.database this.Connect(this.ConnectionString); } + private async Task CheckConnectionAsync() + { + if ((this._con == null) || + (this._con.State == ConnectionState.Closed)) + await this.ConnectAsync(this.ConnectionString); + } + private void LogNonQueryResult(string query, int queryResult) { switch (queryResult) @@ -1537,7 +1563,7 @@ namespace bsmd.database cmd.Connection = this._con; // Stopwatch sw = new Stopwatch(); // sw.Start(); - reader = cmd.ExecuteReader(); + reader = cmd.ExecuteReader(); // sw.Stop(); // _log.DebugFormat("{1}ms: {0}", cmd.CommandText, sw.ElapsedMilliseconds); @@ -1660,7 +1686,41 @@ namespace bsmd.database bulkCopy.WriteToServer(table); } } - } + } + + #endregion + + #region async DB access methods + + internal async Task PerformCommandAsync(SqlCommand cmd) + { + SqlDataReader reader = null; + + await _asyncSemaphore.WaitAsync(); + try + { + await this.CheckConnectionAsync(); + cmd.Connection = this._con; + reader = await cmd.ExecuteReaderAsync(); + } + catch (SqlException ex) + { + Trace.WriteLine("SQL Exception:" + ex.Message); + _log.Error("Error performing command", ex); + _log.DebugFormat("Query: {0}", cmd.CommandText); + _log.Debug("Parameters:"); + for (int i = 0; i < cmd.Parameters.Count; i++) + { + _log.DebugFormat("{0}:{1}", cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value); + } + } + finally + { + _asyncSemaphore.Release(); + } + + return reader; + } #endregion