Answered by:
Multithreaded / Asynchronous Operations in WHS console (GUI side)

Question
-
Wondering if there are any known-issues, best practices or recommendations when tackling threading or asynchronous operations inside of the WHS console- GUI related…
For example I have a fancy list view that populates and other certain tasks are somewhat lengthy; I found very little guidance on this subject, what is one to do just use threads? Backgroundworker or simple methodinvokers? I think none of the WHS controls are thread safe either?Monday, December 1, 2008 12:49 AMModerator
Answers
-
No, there really isn't any guidance besides the Dev Guidelines which basically say "if it's a long-running task, get a Windows service to do it." As far as I know, none of the WHS controls are thread safe.
I'm using a BackgroundWorker in the current stable release of WHS Disk Management. It works ok, but it's a bit inflexible. The latest alpha of WHS Disk Management uses a Windows service for all the heavy lifting, and then a bunch of threads that I create as needed to do GUI updates. Have to worry about race conditions etc (I probably use lock far too much!), of course, but it feels a lot more responsive and is easier to control.
Haven't run into any WHS-specific issues with threading.- Marked as answer by Jonas Svensson -FST- Saturday, January 24, 2009 8:18 PM
Monday, December 1, 2008 4:40 AMModerator
All replies
-
No, there really isn't any guidance besides the Dev Guidelines which basically say "if it's a long-running task, get a Windows service to do it." As far as I know, none of the WHS controls are thread safe.
I'm using a BackgroundWorker in the current stable release of WHS Disk Management. It works ok, but it's a bit inflexible. The latest alpha of WHS Disk Management uses a Windows service for all the heavy lifting, and then a bunch of threads that I create as needed to do GUI updates. Have to worry about race conditions etc (I probably use lock far too much!), of course, but it feels a lot more responsive and is easier to control.
Haven't run into any WHS-specific issues with threading.- Marked as answer by Jonas Svensson -FST- Saturday, January 24, 2009 8:18 PM
Monday, December 1, 2008 4:40 AMModerator -
Sam covered things pretty well, and I'll throw in my experience so far. Remote Notification runs as a service, in hindsight I should have put the Send Sample Notification in a thread as it locks the Console when it times out due to an error. Fortunately this only about 30 seconds or so. Fan Control doesn't use threads either, and locks up the Console for a couple seconds while restarting the MSS services. I got (a little) smarter with BDBB and run the backup process in a backgroundworker thread, however ideally it would run in a service when the user kicks off a backup or restore.
So, no real best practices other than keep any heavy lifting or long-running tasks out of the Console.
http://www.mediasmartserver.netMonday, December 1, 2008 7:34 PMModerator -
The notion of letting a windows service do the crunching is pretty much on-par with how I have handled this in the past... I am however working on something that has a lot more of a WHS GUI presence (custom GDI+ drawn stuff too) and right now my threads are out of control (too many critical sections) and at times the presentation layer feels slugish (need to refactor code) so I figured it wouldn’t hurt to ask in case someone has a silver bullet of sorts ;)
Thanks guys – I appreciate it;Wednesday, December 3, 2008 2:37 AMModerator -
Alexander Kent said:Up your minimum system requirements ;)
a silver bullet of sorts ;)
Can you give us a hint on what your custom GDI+ stuff is? Sounds intriguing.Wednesday, December 3, 2008 5:18 AMModerator -
i.e. –couple of owner drawn controls such as the fancyListView to have special graphics drawn inside column(s) fields other than say the provided progressbar functionality. This seems to work well with just the occasional hiccup that I am still trying to pinpoint $#%#$#.
I guess the only other alternative in this case would be to GDI+ draw the thing as an image and throw it into an imagelist at runtime and then have the fancyListView use the imagelist… only problem would be the image size constrain for subsequent fields.Thursday, December 4, 2008 4:23 PMModerator -
Alexander Kent said:
i.e. –couple of owner drawn controls such as the fancyListView to have special graphics drawn inside column(s) fields other than say the provided progressbar functionality. This seems to work well with just the occasional hiccup that I am still trying to pinpoint $#%#$#.
I guess the only other alternative in this case would be to GDI+ draw the thing as an image and throw it into an imagelist at runtime and then have the fancyListView use the imagelist… only problem would be the image size constrain for subsequent fields.
Sounds like fun.
What are the hiccups you're seeing? I found that BeginUpdate() and EndUpdate() are my friends if I'm trying to do major updates to a FancyListView.Friday, December 5, 2008 9:16 PMModerator -
Hi Sam,
I decided early on not to be using any dataset or datatables, since I could not bind them dynamically to say a fancylistview – instead rather I figured I could just populate a <list> of ListViewItem (s) say something like having a class AddressBookItem : ListViewItemand then have a method say BuildAddressBookView() which will do something like
this.SubItems.Clear();
this.Text = this.FileName;
this.SubItems.Add(this.Name);
this.SubItems.Add(this.Age);
return this;
to build the current “AddressBookView” and perhaps have another method with different fields to build the “BussinessCardView” and again return “this” aswell; (key there is that subitems.clear() ensures that this does not have any junk leftover from any previous Build calls; - and this seems to work well and I am happy with the OO nature… one problem I run into is that having non static column fields I cannot say use one set of enum ColumnFields (like say shown on your blog) –unless I would want to create every single possible column field and then just hide them by setting width to 0 but that would suck! So when implementing any sorting i.e. ListViewColumnSorter I had to go to great length to match a SortColumn (int) column index to a particular column to determine how to handle it based on the current view.
Had to use a static field or could use a delagete so that the customsorter may check this public field to determine the column that was clicked and use that like:switch (MainTabUserControl.columnSortClickName.ToLower())
{
case "age":
// sort as number
break;
}
Ultimately I am happy that I can now sort dynamically allocated fields and GDI+ drawn items too and build it nicely using something like
FancyListView.Items.Add(item.ConvertToListView(ViewType.AddressBook));
// or
FancyListView.Items.Add(item.ConvertToListView(ViewType.BusinessCard));
Etc.Your blog helped a lot too – thank you
Wednesday, December 10, 2008 10:58 PMModerator -
Ah, that's a cool way to do it. Glad I could help!
Did you have a look at programatically adding and removing different FancyListView controls (to represent your different views), or even plugging in a different ListViewColumnSorter based on which view you're in?
Sounds like an interesting add-in you're building :)
Tentacle Blog: http://www.tentaclesoftware.com/blog/ WHS Disk Management: http://www.tentaclesoftware.com/WHSDiskManagement/Thursday, December 11, 2008 6:37 AMModerator