I posted the following to the .NET CF newsgroup this morning:
The Microsoft.WindowsMobile.Status.SystemState class offers a great way to track a number of interesting and useful device system states (e.g., incoming phone calls, battery strength, etc.). However, recently I observed that the SystemState.Changed += new ChangeEventHandler(OnSystemStateChanged) subscription must be made from the UI thread. Has anyone else run into this? I attempted to write a console app that uses many of these system state notifications; however, none of the events were actually occurring. Once I switched to a form-based application, everything worked great.
Is this documented somewhere? If so, I couldn't find it. I am programming in .NET CF 2 for Windows Mobile 5.0 devices.
Chris Tacke responded with,
Most of those events come from windows messages being posted at a low level (FileSystemWatcher works int he same way too). If you never call Application.Run, no message pump is ever created, so no windows messages are ever dispatched.
I don't think I've ever seen it documented, but if you walk through the aygshell source code in Platform Builder (which a lot of these come from eventually), you'll see that's how they work. I agree that it's a poor choice, but it's how it was implemented. The workaround is a very long, tedious process (again, we've done it for file system notifications) of reimplementing the entire listening system, creating a hidden window for your app or implementing a Run() that doesn't take a Form (like we did in the SDF).
Showing posts with label Threads. Show all posts
Showing posts with label Threads. Show all posts
Friday, October 26, 2007
Thursday, January 11, 2007
Keeping SqlCeConnection Open and Thread Safety
I've done quite a bit of searching online and it's fairly clear that there is a bit of confusion about how one should use the SqlCeConnection object, particularly with regards to two interrelated issues: (1) whether to keep the SqlCeConnection open and (2) whether the SqlCeConnection is thread safe. For example, some people advocate for keeping one static SqlCeConnection open and shared for the lifetime of an application. However, if the application is multithreaded, can we assume that we can safely share the connection object? I've blogged about this once before here.
I think some of this confusion stems from the differences between the desktop version of SQL Server (SqlConnection) and SQL Server Mobile (SqlCeConnection). For example, in a MSDN forum post, Dave Hayden (a .NET/C# MS MVP) suggests that "For 99% of all applications, the best practice is to open and dispose of database connections right when you need them and not to leave them open for the duration of the application. Open the database connection as late as possible and close/dispose of it as soon as possible." If, like Dave recommends, we always open a local connection within our method calls (and do not access the SQL connection as a state object), we don't really have to worry about the thread safety of the SQL connection object.
Although this may be good advice for accessing SQL Server from the desktop, it contradicts the advice given by Microsoft developer Marcus Perryman in his SQL Mobile post on his blog, "The SqlCeConnection class implements the IDisposable interface because it allocates a number of unmanaged resources, and therefore the code must call Dispose() on the object before it goes out of scope to ensure these resources are cleaned up in a timely manner. Creating and destroying SQL Mobile database connections is an expensive task and so the SqlCeConnection is designed to be a long lived, shared instance across the lifetime of the application.".
Thus, it appears that Dave and Marcus contradict each other. However, Dave's advice was (I believe) given under the assumption that the person was using SQL Server and not SQL Server Mobile. So, it looks like the correct usage of the SqlCeConnection object is to reduce the amount of creating and destroying SQL Mobile database connections (the reasoning behind this is that SQL Server Mobile supposedly does not have connection pooling, see Marcus Perry link above).
So, then what about thread safety? The MSDN documentation is clear. Most objects within the SQL Mobile namespace are not threadsafe. For example, the SqlCeConnection documentation states, "Any public static members of this type are thread safe. Any instance members are not guaranteed to be thread safe." Thus, instance methods like BeginTransaction(), CreateCommand(), etc. are not thread safe. I'm not sure what the detriment/exception would be if this was not followed, but MSDN is clear, SqlCeConnection was not meant to be shared across threads.
OK, so what if you have a multithreaded application? It seems like there are two prevailing methods: (1) Marcus Perry suggests that "for a complex app, ideally the SqlCeConnection instance would be placed in a singleton wrapper class that manages access to the database." or (2) Ginny Caughey (MS MVP) offers the other approach, using a separate SqlCeConnection object for each thread. For the first approach, I would imagine the simplest wrapper possible may look something like the following (I will implement it as a static class rather than a singleton):
static class SqlWrapper
{
private static SqlCeConnection _sqlCeConnection;
private static object _objLock = new object();
static void Open(string connectionString)
{
lock (_objLock)
{
if (_sqlCeConnection != null)
throw new InvalidOperationException("Connection already open.");
_sqlCeConnection = new SqlCeConnection(connectionString);
}
}
static void Close()
{
lock (_objLock)
{
if (_sqlCeConnection != null)
{
_sqlCeConnection.Dispose();
_sqlCeConnection = null;
}
}
}
static int ExecuteNonQuery(SqlCeCommand sqlCommand)
{
lock (_objLock)
{
sqlCommand.Connection = _sqlCeConnection;
return sqlCommand.ExecuteNonQuery();
}
}
static SqlCeDataReader ExecuteReader(SqlCeCommand sqlCommand)
{
lock (_objLock)
{
sqlCommand.Connection = _sqlCeConnection;
return sqlCommand.ExecuteReader();
}
}
}
Does this seem right to people? In this class, we do not expose the underlying SqlCeConnection object, thus commands must be passed in via the wrapper interface to be executed (as they require a reference to a SqlCeConnection).
For the second approach, one connection per thread, the difficulty isn't necessarily in opening 1 connection per thread but knowing when to close those connections. In other words, a SqlCeConnectionManager class might manage access to SqlCeConnections and might serve as a SqlCeConnection factory (with, perhaps, an underlying connection pool). The factory may look at which thread is active (Thread.CurrentThread), check to see if a connection has been allocated for that thread (create one if not) and return the SqlCeConnection. However, the onus would be on the threads themselves to close their connections before exiting (this seems messy to me). I suppose one could spawn a monitoring thread that looked as the status of Threads and, once dead, would either close the respective SqlCeConnection or return the connection the connection pool. However, .NET CF 2.0 does not support the instance property IsAlive so it's not clear how one could do this.
I would imagine that a multithreaded application that launches many short-lived threads that need database access should probably go with the SQL wrapper solution as the overhead of opening/closing connections would introduce a performance hit (even with connection pooling).
An interesting side note: I created a test app on the mobile phone which launched 50 threads on a shared SqlCeConnection and proceeded to read/write random bits of data. No exception was thrown. Of course, the lack of error does not mean that it will always work.
I think some of this confusion stems from the differences between the desktop version of SQL Server (SqlConnection) and SQL Server Mobile (SqlCeConnection). For example, in a MSDN forum post, Dave Hayden (a .NET/C# MS MVP) suggests that "For 99% of all applications, the best practice is to open and dispose of database connections right when you need them and not to leave them open for the duration of the application. Open the database connection as late as possible and close/dispose of it as soon as possible." If, like Dave recommends, we always open a local connection within our method calls (and do not access the SQL connection as a state object), we don't really have to worry about the thread safety of the SQL connection object.
Although this may be good advice for accessing SQL Server from the desktop, it contradicts the advice given by Microsoft developer Marcus Perryman in his SQL Mobile post on his blog, "The SqlCeConnection class implements the IDisposable interface because it allocates a number of unmanaged resources, and therefore the code must call Dispose() on the object before it goes out of scope to ensure these resources are cleaned up in a timely manner. Creating and destroying SQL Mobile database connections is an expensive task and so the SqlCeConnection is designed to be a long lived, shared instance across the lifetime of the application.".
Thus, it appears that Dave and Marcus contradict each other. However, Dave's advice was (I believe) given under the assumption that the person was using SQL Server and not SQL Server Mobile. So, it looks like the correct usage of the SqlCeConnection object is to reduce the amount of creating and destroying SQL Mobile database connections (the reasoning behind this is that SQL Server Mobile supposedly does not have connection pooling, see Marcus Perry link above).
So, then what about thread safety? The MSDN documentation is clear. Most objects within the SQL Mobile namespace are not threadsafe. For example, the SqlCeConnection documentation states, "Any public static members of this type are thread safe. Any instance members are not guaranteed to be thread safe." Thus, instance methods like BeginTransaction(), CreateCommand(), etc. are not thread safe. I'm not sure what the detriment/exception would be if this was not followed, but MSDN is clear, SqlCeConnection was not meant to be shared across threads.
OK, so what if you have a multithreaded application? It seems like there are two prevailing methods: (1) Marcus Perry suggests that "for a complex app, ideally the SqlCeConnection instance would be placed in a singleton wrapper class that manages access to the database." or (2) Ginny Caughey (MS MVP) offers the other approach, using a separate SqlCeConnection object for each thread. For the first approach, I would imagine the simplest wrapper possible may look something like the following (I will implement it as a static class rather than a singleton):
static class SqlWrapper
{
private static SqlCeConnection _sqlCeConnection;
private static object _objLock = new object();
static void Open(string connectionString)
{
lock (_objLock)
{
if (_sqlCeConnection != null)
throw new InvalidOperationException("Connection already open.");
_sqlCeConnection = new SqlCeConnection(connectionString);
}
}
static void Close()
{
lock (_objLock)
{
if (_sqlCeConnection != null)
{
_sqlCeConnection.Dispose();
_sqlCeConnection = null;
}
}
}
static int ExecuteNonQuery(SqlCeCommand sqlCommand)
{
lock (_objLock)
{
sqlCommand.Connection = _sqlCeConnection;
return sqlCommand.ExecuteNonQuery();
}
}
static SqlCeDataReader ExecuteReader(SqlCeCommand sqlCommand)
{
lock (_objLock)
{
sqlCommand.Connection = _sqlCeConnection;
return sqlCommand.ExecuteReader();
}
}
}
Does this seem right to people? In this class, we do not expose the underlying SqlCeConnection object, thus commands must be passed in via the wrapper interface to be executed (as they require a reference to a SqlCeConnection).
For the second approach, one connection per thread, the difficulty isn't necessarily in opening 1 connection per thread but knowing when to close those connections. In other words, a SqlCeConnectionManager class might manage access to SqlCeConnections and might serve as a SqlCeConnection factory (with, perhaps, an underlying connection pool). The factory may look at which thread is active (Thread.CurrentThread), check to see if a connection has been allocated for that thread (create one if not) and return the SqlCeConnection. However, the onus would be on the threads themselves to close their connections before exiting (this seems messy to me). I suppose one could spawn a monitoring thread that looked as the status of Threads and, once dead, would either close the respective SqlCeConnection or return the connection the connection pool. However, .NET CF 2.0 does not support the instance property IsAlive so it's not clear how one could do this.
I would imagine that a multithreaded application that launches many short-lived threads that need database access should probably go with the SQL wrapper solution as the overhead of opening/closing connections would introduce a performance hit (even with connection pooling).
An interesting side note: I created a test app on the mobile phone which launched 50 threads on a shared SqlCeConnection and proceeded to read/write random bits of data. No exception was thrown. Of course, the lack of error does not mean that it will always work.
Get Control From Handle
I have not yet determined a clean way to invoke code on the UI thread without access to a Form/Control. The Process class has a property called "MainWindowHandle," which returns the window handle of the main window of the associated process. So, for example, Process.GetCurrentProcess().MainWindowHandle would return a Handle (HWND) to the main window. But how can we translate a window handle to a Form?
In .NET 2.0, this is relatively easy, we can simply call Control.FromHandle(IntPtr handle). Thus, receiving access to the main window is simply:
(Form)Control.FromHandle(Process.GetCurrentProcess().MainWindowHandle)
Unfortunately, however, .NET CF 2.0 does not expose the Control.FromHandle method. I have not found anyone on the web who has solved this problem. A few relevant links:
1. How do I get System.Control object from a Win32 Handle?
2. Google Groups.
Given the limitations of CF, one hacky way to do this would be to expose a static property on your MainForm class which would return a reference to itself. This would actually work in my case as the MainForm should not be instantiated more than once.
Update 01/30/2007: I just made a post to Google Groups about this (link).
In .NET 2.0, this is relatively easy, we can simply call Control.FromHandle(IntPtr handle). Thus, receiving access to the main window is simply:
(Form)Control.FromHandle(Process.GetCurrentProcess().MainWindowHandle)
Unfortunately, however, .NET CF 2.0 does not expose the Control.FromHandle method. I have not found anyone on the web who has solved this problem. A few relevant links:
1. How do I get System.Control object from a Win32 Handle?
2. Google Groups.
Given the limitations of CF, one hacky way to do this would be to expose a static property on your MainForm class which would return a reference to itself. This would actually work in my case as the MainForm should not be instantiated more than once.
Update 01/30/2007: I just made a post to Google Groups about this (link).
Sunday, April 09, 2006
SqlCeConnection Keep Connection Open?
Consensus seems to point to keeping one instance of SqlCeConnection open for the duration of executation for performance reasons.
Though this information comes from a Microsoft employee, it still seems contentious. Dave Hayden, a MS MVP, said in this MSDN forum post:
Nicholas Paldino (a .NET/C# MVP) seems to agree with Dave:
Both Dave and Nicholas are basing their advice on SQL Server's behavior (not SQL Server Mobile). SQL Server supports connection pooling, SQL Server Mobile does not. Again, from MS Employee Marcus Perry (link),
If only one SqlCeConnection is used, note that it is not thread safe. Thus, a multithread application must provide mechanisms to safely access the SQL database from multiple threads. There seem to be two approaches: one is to make the singleton wrapper class (mentioned above) thread safe and the other is to give each thread access to its own SqlCeConnection object. See these MSDN forum posts (here and here). Microsoft has yet to endorse a specific approach as a "best practice" (a discussion about this can be found here).
- SqlCeConnection guidelines (MSDN Forums)
- Performance with SqlCeConnection (Usenet)
- Data Architecture & Pooling (Usenet) <- this is for SqlServerCe 2003
Creating and destroying SQL Mobile database connections is an expensive task and so the SqlCeConnection is designed to be a long lived, shared instance across the lifetime of the application. For a complex app, ideally the SqlCeConnection instance would be placed in a singleton wrapper class that manages access to the database.
Though this information comes from a Microsoft employee, it still seems contentious. Dave Hayden, a MS MVP, said in this MSDN forum post:
For 99% of all applications, the best practice is to open and dispose of database connections right when you need them and not to leave them open for the duration of the application. Open the database connection as late as possible and close/dispose of it as soon as possible.
Nicholas Paldino (a .NET/C# MVP) seems to agree with Dave:
You shouldn't keep a connection open and lying around. The SqlConnection class uses a connection pool in the background, and keeping your connection open is actually going to degrade your performance. You will want to create a new connection, open it, use it, and then close it for every operation that you do (or group of operations). You shouldn't be holding the connection open across operations. You will also notice MUCH better performance when you do this. The same thing holds with the command object. Don't use the same one. Use new ones. If you want to use a command object over and over again, you can, but use it for the same parameterized command. Don't keep changing the command string.
Both Dave and Nicholas are basing their advice on SQL Server's behavior (not SQL Server Mobile). SQL Server supports connection pooling, SQL Server Mobile does not. Again, from MS Employee Marcus Perry (link),
There is no connection pool used for local database access for SQL Mobile.
If only one SqlCeConnection is used, note that it is not thread safe. Thus, a multithread application must provide mechanisms to safely access the SQL database from multiple threads. There seem to be two approaches: one is to make the singleton wrapper class (mentioned above) thread safe and the other is to give each thread access to its own SqlCeConnection object. See these MSDN forum posts (here and here). Microsoft has yet to endorse a specific approach as a "best practice" (a discussion about this can be found here).
Thursday, February 09, 2006
Lock on this?
When writing attempting to write threadsafe code in C#, I'm always debating whether to lock on 'this' or some Object in existence purely for synchronization. Here are a few links contributing to this debate:
1. .NET Safe Thread Synchronization
2. Lock Choice
1. .NET Safe Thread Synchronization
2. Lock Choice
Wednesday, August 03, 2005
Curiosities of Control.Invoke...
I wrote about Control.Invoke(Delegate) once before with regards to the .NET CF restriction that the delegate must be an instance of the EventHandler. See the original post.
I was always curious though about Control.Invoke and whether or not it would act in a comparable manner to firing an event in the normal way (e.g. myEvent(this, EventArgs.Empty)). Is Control.Invoke essentially the same thing? The only obvious difference being that the event execution is transferred to the thread that owns the control's underlying window handle.
I finally got around to writing a little test util to verify its behavior. My strange conceptual suspicions/thoughts about what it might do were laid to rest and the reality has taken its place. Control.Invoke on an event delegate with multiple subscribers will iterate through each subscriber and fire the event (just as if you fired the event yourself -- in the non-Invoke manner).
I was always curious though about Control.Invoke and whether or not it would act in a comparable manner to firing an event in the normal way (e.g. myEvent(this, EventArgs.Empty)). Is Control.Invoke essentially the same thing? The only obvious difference being that the event execution is transferred to the thread that owns the control's underlying window handle.
I finally got around to writing a little test util to verify its behavior. My strange conceptual suspicions/thoughts about what it might do were laid to rest and the reality has taken its place. Control.Invoke on an event delegate with multiple subscribers will iterate through each subscriber and fire the event (just as if you fired the event yourself -- in the non-Invoke manner).
Sunday, July 24, 2005
Thread Safe Singleton
Typical WinForms applications are typically running in the UI thread, so the simple singleton will provide you with the functionality that you're looking for. However, if you are creating a multi-threaded application that needs to access a singleton across all of its threads, then you will need to create a thread-safe singleton class instead. What you gain in functionality comes at the cost of some performance, so you shouldn't use this form of the class unless you actually intend to use the class from multiple threads.
Thread Safe Singleton Code
Thread Safe Singleton Code
Saturday, July 23, 2005
No Thread.Abort() in .NET CF 1.0
You cannot call Thread.Abort() in .NET CF 1.0, so how do you close/stop a thread?
See this HOWTO on msdn for a workaround.
See this HOWTO on msdn for a workaround.
Subscribe to:
Posts (Atom)
