[Roam-commit] SF.net SVN: roam: [116] Trunk/Source
Status: Alpha
Brought to you by:
jonfroehlich
|
From: <jon...@us...> - 2008-02-19 22:55:05
|
Revision: 116
http://roam.svn.sourceforge.net/roam/?rev=116&view=rev
Author: jonfroehlich
Date: 2008-02-19 14:55:01 -0800 (Tue, 19 Feb 2008)
Log Message:
-----------
1. fixed bug in SplashForm that caused empty log statements from printing
2. fixed bug in SqlCeConnectionManager where the number of PooledConnectionsCount were misreported
Modified Paths:
--------------
Trunk/Source/Roam.SqlCe/SqlCeConnectionManager.cs
Trunk/Source/Roam.Test/Roam.Test.csproj
Trunk/Source/Roam.UI/Forms/SplashForm.cs
Trunk/Source/Roam.suo
Modified: Trunk/Source/Roam.SqlCe/SqlCeConnectionManager.cs
===================================================================
--- Trunk/Source/Roam.SqlCe/SqlCeConnectionManager.cs 2008-02-12 12:34:09 UTC (rev 115)
+++ Trunk/Source/Roam.SqlCe/SqlCeConnectionManager.cs 2008-02-19 22:55:01 UTC (rev 116)
@@ -37,29 +37,74 @@
{
private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(SqlCeConnectionManager));
+ #region Fields
private static ConnectionPool _connectionPool;
private static object _objLock = new object();
-
+ #endregion Fields
+
+ #region Properties
+ /// <summary>
+ /// Gets whether or not the SqlCeConnectionManager has been initialized
+ /// </summary>
public static bool IsInitialized
{
- get { lock (_objLock) { return _connectionPool != null; } }
+ get
+ {
+ lock (_objLock)
+ {
+ return _connectionPool != null;
+ }
+ }
}
+ /// <summary>
+ /// Gets the connection string that was used to open the SqlCeConnection
+ /// </summary>
public static string ConnectionString
{
- get { lock (_objLock) { return (_connectionPool==null) ? "" : _connectionPool.ConnectionString; } }
+ get
+ {
+ lock (_objLock)
+ {
+ return (_connectionPool==null) ? "" : _connectionPool.ConnectionString;
+ }
+ }
}
+ /// <summary>
+ /// Gets the number of SqlCeConnections that are currently pooled
+ /// </summary>
public static int PooledConnectionsCount
{
- get { lock (_objLock) { return (_connectionPool == null) ? 0 : _connectionPool.PooledConnectionsCount; } }
+ get
+ {
+ lock (_objLock)
+ {
+ return (_connectionPool == null) ? 0 : _connectionPool.PooledConnectionsCount;
+ }
+ }
}
+ /// <summary>
+ /// Gets the number of SqlCeConnections that are currently opened
+ /// </summary>
public static int OpenedConnectionsCount
{
- get { lock (_objLock) { return (_connectionPool == null) ? 0 : _connectionPool.PooledConnectionsCount; } }
+ get
+ {
+ lock (_objLock)
+ {
+ return (_connectionPool == null) ? 0 : _connectionPool.OpenedConnectionsCount;
+ }
+ }
}
+ #endregion Properties
+ #region Methods
+ /// <summary>
+ /// Initializes the SqlCeConnectionManager with the given connectionString
+ /// </summary>
+ /// <param name="connectionString"></param>
public static void Initialize(string connectionString)
{
Stopwatch sw = Stopwatch.StartNew();
@@ -67,7 +112,8 @@
{
if (_connectionPool != null)
{
- InvalidOperationException ioe = new InvalidOperationException("The SqlConnectionManager has already been initialized, call CloseAllConnections and then Initialize");
+ InvalidOperationException ioe =
+ new InvalidOperationException("The SqlConnectionManager has already been initialized, call CloseAllConnections and then Initialize");
_log.Error(ioe.Message, ioe);
throw ioe;
}
@@ -86,7 +132,8 @@
{
if (_connectionPool == null)
{
- InvalidOperationException ioe = new InvalidOperationException("The SqlConnectionManager must be initialized before calling GetConnection");
+ InvalidOperationException ioe =
+ new InvalidOperationException("The SqlConnectionManager must be initialized before calling GetConnection");
_log.Error(ioe.Message, ioe);
throw ioe;
}
@@ -95,16 +142,30 @@
}
/// <summary>
- /// Closes the SqlCeConnection for the current thread (if one exists). Returns true if the
- /// connection was closed successfully, false otherwise.
+ /// This method is for debugging purposes only, do not change/modify the
+ /// Thread or SqlCeConnection objects
/// </summary>
+ /// <returns></returns>
+ public static IDictionary<Thread, SqlCeConnection> GetActiveConnections()
+ {
+ lock (_objLock)
+ {
+ return _connectionPool.ActiveConnections;
+ }
+ }
+
+ /// <summary>
+ /// Closes the SqlCeConnection for the current thread (if one exists).
+ /// </summary>
+ /// <returns>Returns true if the connection was closed successfully, false otherwise.</returns>
public static bool CloseConnection()
{
lock (_objLock)
{
if (_connectionPool == null)
{
- InvalidOperationException ioe = new InvalidOperationException("The SqlConnectionManager must be initialized before calling GetConnection");
+ InvalidOperationException ioe =
+ new InvalidOperationException("The SqlConnectionManager must be initialized before calling GetConnection");
_log.Error(ioe.Message, ioe);
throw ioe;
}
@@ -113,7 +174,7 @@
}
/// <summary>
- /// Closes all open SqlCeConnections across all threads.
+ /// Closes all open and pooled SqlCeConnections across all threads.
/// </summary>
public static void CloseAllConnections()
{
@@ -121,11 +182,54 @@
{
if (_connectionPool != null)
{
+ _connectionPool.CloseAllConnections();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Closes all active SqlCeConnections across all threads.
+ /// </summary>
+ public static void CloseAllActiveConnections()
+ {
+ lock (_objLock)
+ {
+ if (_connectionPool != null)
+ {
+ _connectionPool.CloseAllActiveConnections();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Closes all pooled SqlCeConnections across all threads.
+ /// </summary>
+ public static void CloseAllPooledConnections()
+ {
+ lock (_objLock)
+ {
+ if (_connectionPool != null)
+ {
+ _connectionPool.CloseAllPooledConnections();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Disposes all connections and sets the connection pool to null
+ /// </summary>
+ public static void Dispose()
+ {
+ lock (_objLock)
+ {
+ if (_connectionPool != null)
+ {
_connectionPool.Dispose();
_connectionPool = null;
}
}
}
+ #endregion Methods
/// <summary>
///
@@ -137,52 +241,75 @@
class ConnectionPool : IDisposable
{
private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(ConnectionPool));
+ private static readonly int DEFAULT_MAX_POOLED_CONNECTIONS = 5;
- private Dictionary<Thread, SqlCeConnection> _connections = new Dictionary<Thread, SqlCeConnection>();
- private Stack<SqlCeConnection> _pooledConnections = new Stack<SqlCeConnection>(5);
+ #region Fields
+ private Dictionary<Thread, SqlCeConnection> _activeConnections =
+ new Dictionary<Thread, SqlCeConnection>(new ThreadKeyComparer());
+ private Stack<SqlCeConnection> _pooledConnectionsStack;
/// <summary>
- /// The minimum number of connections kept in the connection pool
+ /// The maximum number of connections kept in the connection pool
/// </summary>
- private int _minPooledConnections = 5;
+ private int _maxPooledConnections = DEFAULT_MAX_POOLED_CONNECTIONS;
private object _objLock = new object();
private string _connectionString;
+ #endregion Fields
- public ConnectionPool(string connectionString) : this(connectionString, 5) { }
+ #region Constructors
+ public ConnectionPool(string connectionString)
+ : this(connectionString, DEFAULT_MAX_POOLED_CONNECTIONS) { }
- public ConnectionPool(string connectionString, int minimumPooledConnections)
+ public ConnectionPool(string connectionString, int maxPooledConnections)
{
_connectionString = connectionString;
- _minPooledConnections = minimumPooledConnections;
+ _maxPooledConnections = maxPooledConnections;
- _log.DebugFormat("ConnectionPool created with ConnectionString={0} and MinimumPooledConnections={1}",
- _connectionString, _minPooledConnections);
+ _pooledConnectionsStack = new Stack<SqlCeConnection>(maxPooledConnections);
+
+ _log.DebugFormat("ConnectionPool created with ConnectionString={0} and MaximumPooledConnections={1}",
+ _connectionString, _maxPooledConnections);
}
+ #endregion Constructors
+ #region Properties
+ /// <summary>
+ /// Gets the connection string used for the ConnectionPool
+ /// </summary>
public string ConnectionString
{
get { return _connectionString; }
}
- public int MinimumPooledConnections
+ /// <summary>
+ /// Gets the maximum number of pooled connections to maintain
+ /// </summary>
+ public int MaximumPooledConnections
{
- get { return _minPooledConnections; }
+ get { return _maxPooledConnections; }
}
+ /// <summary>
+ /// Gets the current number of pooled connections
+ /// </summary>
public int PooledConnectionsCount
{
- get { return _pooledConnections.Count; }
+ get { return _pooledConnectionsStack.Count; }
}
+ /// <summary>
+ /// Gets the current number of opened connections
+ /// </summary>
public int OpenedConnectionsCount
{
get
{
int openCount = 0;
- foreach (SqlCeConnection sqlConnection in _connections.Values)
+ foreach (SqlCeConnection sqlConnection in _activeConnections.Values)
{
- if ((sqlConnection.State & System.Data.ConnectionState.Open) == System.Data.ConnectionState.Open)
+ if ((sqlConnection.State & System.Data.ConnectionState.Open)
+ == System.Data.ConnectionState.Open)
{
openCount++;
}
@@ -191,16 +318,38 @@
}
}
+ /// <summary>
+ /// This property is for debugging purposes only, do not change the Thread
+ /// or SqlCeConnection objects in the returned Dictionary
+ /// </summary>
+ public IDictionary<Thread, SqlCeConnection> ActiveConnections
+ {
+ get
+ {
+ lock (_objLock)
+ {
+ return new Dictionary<Thread, SqlCeConnection>(_activeConnections);
+ }
+ }
+ }
+ #endregion Properties
+
+ #region Methods
public void Dispose()
{
lock (_objLock)
{
CloseAllConnections();
- _connections.Clear();
- _pooledConnections.Clear();
+ _activeConnections = null;
+ _pooledConnectionsStack = null;
}
}
+ /// <summary>
+ /// Opens an SqlCeConnection for the current thread. If a connection already exists for the
+ /// current thread, that SqlCeConnection is used.
+ /// </summary>
+ /// <returns></returns>
public SqlCeConnection Open()
{
lock (_objLock)
@@ -209,6 +358,7 @@
SqlCeConnection sqlConn;
Thread threadCurrent = Thread.CurrentThread;
+ #region DEBUG
//debug
//_log.InfoFormat("There are {0} items in _connections", _connections.Count);
//_log.InfoFormat("The current thread={0} with managed thread id={1}", threadCurrent.Name, threadCurrent.ManagedThreadId);
@@ -217,25 +367,26 @@
// _log.InfoFormat("{0} ({1}): {2}", kvp.Key.Name, kvp.Key.ManagedThreadId, kvp.Value.ConnectionString);
//}
//end debug
+ #endregion DEBUG
- if (_connections.ContainsKey(threadCurrent))
+ if (_activeConnections.ContainsKey(threadCurrent))
{
_log.DebugFormat("Open : The current thread {0} has an assigned connection", threadCurrent.Name);
- sqlConn = _connections[threadCurrent];
+ sqlConn = _activeConnections[threadCurrent];
}
- else if (_pooledConnections.Count > 0)
+ else if (_pooledConnectionsStack.Count > 0)
{
_log.DebugFormat("Open : The number of pooled connections={0}, assigning thread {1} a pooled connection",
- _pooledConnections.Count, threadCurrent.Name);
- sqlConn = _pooledConnections.Pop();
+ _pooledConnectionsStack.Count, threadCurrent.Name);
+ sqlConn = _pooledConnectionsStack.Pop();
}
else
{
_log.DebugFormat("Open : The number of pooled connections={0}, assigning thread {1} a new connection",
- _pooledConnections.Count, threadCurrent.Name);
+ _pooledConnectionsStack.Count, threadCurrent.Name);
sqlConn = new SqlCeConnection(_connectionString);
}
- _connections[threadCurrent] = sqlConn;
+ _activeConnections[threadCurrent] = sqlConn;
if (sqlConn.State == System.Data.ConnectionState.Closed)
{
@@ -243,12 +394,25 @@
sqlConn.Open();
}
- _log.DebugFormat("Open : There are {0} connections open and {1} pooled connections", OpenedConnectionsCount, PooledConnectionsCount);
- _log.DebugFormat("Open : Successfully opened connection for thread {0} in {1} ms", threadCurrent.Name, sw.ElapsedMilliseconds);
+ //most efficient to check for this flag before logging
+ if (_log.IsDebugEnabled)
+ {
+ _log.DebugFormat("Open : There are {0} connections open and {1} pooled connections",
+ OpenedConnectionsCount, PooledConnectionsCount);
+
+ _log.DebugFormat("Open : Successfully opened connection for thread '{0}' in {1} ms",
+ threadCurrent.Name, sw.ElapsedMilliseconds);
+ }
return sqlConn;
}
}
+ /// <summary>
+ /// Closes the active SQL connection for the current thread. If the maximum pooled
+ /// connections count has not yet been reached, this connection may be added to the
+ /// connection pool, otherwise it is immediately closed
+ /// </summary>
+ /// <returns></returns>
public bool Close()
{
lock (_objLock)
@@ -257,6 +421,7 @@
Thread threadCurrent = Thread.CurrentThread;
bool returnVal = false;
+ #region DEBUG
//debug
//_log.InfoFormat("There are {0} items in _connections", _connections.Count);
//_log.InfoFormat("The current thread={0} with managed thread id={1}", threadCurrent.Name, threadCurrent.ManagedThreadId);
@@ -265,26 +430,33 @@
// _log.InfoFormat("{0} ({1}): {2}", kvp.Key.Name, kvp.Key.ManagedThreadId, kvp.Value.ConnectionString);
//}
//end debug
+ #endregion DEBUG
- if (_connections.ContainsKey(threadCurrent))
+ if (_activeConnections.ContainsKey(threadCurrent))
{
- SqlCeConnection sqlConn = _connections[threadCurrent];
- _connections.Remove(threadCurrent);
+ SqlCeConnection sqlConn = _activeConnections[threadCurrent];
+ _activeConnections.Remove(threadCurrent);
+ _log.DebugFormat("Close : Removed connection for thread '{0}' with ThreadId={1}",
+ threadCurrent.Name, threadCurrent.ManagedThreadId);
+
//check to see if we should actually close the connection
- if (_pooledConnections.Count > _minPooledConnections)
+ if (_pooledConnectionsStack.Count > _maxPooledConnections)
{
- //Updated 10/10/2007. Do not rely on the thread pool to close the connection
- //ThreadPool.QueueUserWorkItem(new WaitCallback(CloseCallback), sqlConn);
sqlConn.Close();
sqlConn.Dispose();
+
+ _log.DebugFormat("Close : Closed connection for thread '{0}' with ThreadId={1} because the number of pooled connections ({2}) exceeds the maximum pooled connections limit ({3})",
+ threadCurrent.Name, threadCurrent.ManagedThreadId, _pooledConnectionsStack.Count, _maxPooledConnections);
}
else
{
- _pooledConnections.Push(sqlConn);
+ _pooledConnectionsStack.Push(sqlConn);
+
+ _log.DebugFormat("Close : Moved connection for thread '{0}' with ThreadId={1} to connection pool",
+ threadCurrent.Name, threadCurrent.ManagedThreadId);
}
returnVal = true;
- _log.DebugFormat("Close : Closed connection for thread '{0}'", threadCurrent.Name);
}
else
{
@@ -297,37 +469,76 @@
}
}
- public void CloseAllConnections()
+ /// <summary>
+ /// Close all pooled connections
+ /// </summary>
+ public void CloseAllPooledConnections()
{
lock (_objLock)
{
- foreach (SqlCeConnection sqlConn in _connections.Values)
+ int pooledConnectionsCount = _pooledConnectionsStack.Count;
+ foreach (SqlCeConnection sqlConn in _pooledConnectionsStack)
{
sqlConn.Close();
sqlConn.Dispose();
}
+ _pooledConnectionsStack.Clear();
- foreach (SqlCeConnection sqlConn in _pooledConnections)
- {
- sqlConn.Close();
- sqlConn.Dispose();
- }
+ _log.DebugFormat("CloseAllPooledConnections : Successfully closed {0} pooled connections",
+ pooledConnectionsCount);
+ }
+ }
- _connections.Clear();
- _pooledConnections.Clear();
+ /// <summary>
+ /// Close all active connections
+ /// </summary>
+ public void CloseAllActiveConnections()
+ {
+ int connectionsCount = _activeConnections.Count;
+
+ foreach (SqlCeConnection sqlConn in _activeConnections.Values)
+ {
+ sqlConn.Close();
+ sqlConn.Dispose();
}
+
+ _activeConnections.Clear();
+
+ _log.DebugFormat("CloseAllConnections : Successfully closed {0} active connections",
+ connectionsCount);
}
/// <summary>
- /// Called by thread.
+ /// Close all active and pooled connections
/// </summary>
- /// <param name="state"></param>
- private void CloseCallback(object state)
+ public void CloseAllConnections()
{
- SqlCeConnection sqlConn = (SqlCeConnection)state;
- sqlConn.Close();
- sqlConn.Dispose();
+ lock (_objLock)
+ {
+ CloseAllActiveConnections();
+ CloseAllPooledConnections();
+ }
}
+ #endregion Methods
+
+ #region ThreadKeyComparer class
+ class ThreadKeyComparer : IEqualityComparer<Thread>
+ {
+ #region IEqualityComparer<Thread> Members
+
+ public bool Equals(Thread x, Thread y)
+ {
+ return x.ManagedThreadId == y.ManagedThreadId;
+ }
+
+ public int GetHashCode(Thread obj)
+ {
+ return obj.ManagedThreadId.GetHashCode();
+ }
+
+ #endregion
+ }
+ #endregion ThreadKeyComparer class
}
}
}
Modified: Trunk/Source/Roam.Test/Roam.Test.csproj
===================================================================
--- Trunk/Source/Roam.Test/Roam.Test.csproj 2008-02-12 12:34:09 UTC (rev 115)
+++ Trunk/Source/Roam.Test/Roam.Test.csproj 2008-02-19 22:55:01 UTC (rev 116)
@@ -702,7 +702,7 @@
<DependentUpon>SystemColorTest.cs</DependentUpon>
</Compile>
<Compile Include="UI\Controls\TabControlTest.cs">
- <SubType>Form</SubType>
+ <SubType>Component</SubType>
</Compile>
<Compile Include="UI\Controls\TabControlTest.Designer.cs">
<DependentUpon>TabControlTest.cs</DependentUpon>
Modified: Trunk/Source/Roam.UI/Forms/SplashForm.cs
===================================================================
--- Trunk/Source/Roam.UI/Forms/SplashForm.cs 2008-02-12 12:34:09 UTC (rev 115)
+++ Trunk/Source/Roam.UI/Forms/SplashForm.cs 2008-02-19 22:55:01 UTC (rev 116)
@@ -371,17 +371,19 @@
if (_memoryAppender != null)
{
LoggingEvent[] logEvents = _memoryAppender.GetEvents();
-
+ _memoryAppender.Clear();
+
//StringWriter has information stored in underlying StringBuilder
- StringWriter writer = new StringWriter();
-
- _memoryAppender.Clear();
- foreach (LoggingEvent logEvent in logEvents)
+ if (logEvents.Length > 0)
{
- _memoryAppender.Layout.Format(writer, logEvent);
+ StringWriter writer = new StringWriter();
+ foreach (LoggingEvent logEvent in logEvents)
+ {
+ _memoryAppender.Layout.Format(writer, logEvent);
+ }
+ _logBuffer.Add(writer.ToString());
+ bInvalidate = true;
}
- _logBuffer.Add(writer.ToString());
- bInvalidate = true;
}
if (bInvalidate)
Modified: Trunk/Source/Roam.suo
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|