What is the best threading model for database access in a Windows Forms client?
It's a pretty standard setup, WinForms client > Self-serving Business/Data layer > SQL Server (stored procedures).
At the moment, my WinForms call to grab the data will be something like
MyData = RecipientInfo.GetListings(<options>)
. It will then fill the UI with said data, mostly through Binding as all the objects support things like BindingList and INotifyPropertyChanged.
The GetListings()
function does two things. Firstly it gets a list of lookup data, then once that structure is filled from the DataReader, another function will go off and do more database access by calling another objects static GetOtherRelatedStuff(<stuffId>)
method. This will then get sorted and grouped later on.
I suppose my question really is more of a matter of taste, but here are the obvious options if I want to process my SQL (DataReaders and the likes to populate my objects manually) and then do some basic analysis of data whilst the user is waiting.
- Make my initial data access mechanism use the IAsyncResult pattern, my WinForm will expect a callback
- Use the SqlCommands
BeginExecuteReader()
function and callback when ready. This won't help my calling code so I'll have to hook开发者_如何学编程 up a double callback routine to inform the WinForms client about when the job is done - Events? Probably not.
- BackgroundWorker? This is good and I've used this with great success before, but it does feel a bit UI centric (which is really the point of this excersise).
- Use Tasks from Parallel extensions within my WinForms calling code. I'm guessing that my actual data layer code for SQL work will be written synchronously as usual and the WinForm will just take care of running it and processing the UI when it's complete.
In fact, I can also use helpers internally like AsParallel to assist with the extra data getting methods and data grouping/sorting after SQL work is done.
Tasks also make Unit Testing a lot easier as my data access code is written in a way that's easy to execute.
Anything I've missed?
Ok so this was quite a subjective question, but I've decided to go down the route of Tasks from the TPL, executed from my WinForms client.
My "business layer" accepts a CancellationToken for long jobs of work and it's broken down into many specific routines to help parallelise the multi-stage process.
SQL is done synchronously, but run through Tasks it is self-threaded. Although I'm having to carefully consider the WinForms code to comply with the specific data requirements, it's easily broken down, and ties the solution together nicely.
精彩评论