LOL, people still whine about having to do everything asynchronously in Silverlight. When I dove into Silverlight head-first around September, I didn’t know much about asynchronous calls, besides the usual BeginInvoke() calls for long running threads. Needing to use async calls for all data transfers was a bit daunting. For a long time, I tried making all calls synchronous using the dispatcher, wait loops… most anything I could think of. However, I have found that learning async patterns has made me a better programmer, and I would use the async calling model even if I was in desktop WPF/WinForms and had the sync model available to me.
The project I am working on for Morris Consulting (I’m on an NDA, so I can’t go into details) has a list of people represented by buttons whose states can be turned on and off. When I first started to work on the project, I was using all “faked” synchronous calls to get the data. I noticed that the SL app would stall for three seconds while loading all 1000+ people into a custom usercontrol I made. Three seconds is bad, but it’s not horrible, I told myself. But, what if the list was composed of 50,000 people? I would be looking at a pause of two and a half minutes, which is very unacceptable!
Firstly, use the MVVM pattern. Setting up a viewmodel to handle the workload, rather than cowboy-coding it into the UI, is super-beneficial in the long run. It’s testable, and you can use the viewmodel in SL, WPF, WinForms, MVC, or whatever UI you want. You could even use a string tokenizer to take input and make a console app that runs your program. You only have to write your business rules one time, and your different UIs will consume your view model. Mind you, writing a clean, well thought out UI only seems easy, but in some aspects can be harder than writing the business logic! You don’t want to repeat yourself at all, so it’s important you separate your business logic from the UI for any medium to large application.
Your viewmodel should not rely on the UI at all, so no dependency properties should be on it. Use regular properties and INotifyPropertyChanged, and then any XAML binding (or WinForms binding, shudder) won’t have any issues. DO make a base ViewModel class that is used by your view models. DO make a view model that is used by a single view. I’ve used a single view model that is used by a couple views, but I make a copy of it once one of the views needs major changes that could break the first view. Your view models should implement INotifyPropertyChanged for binding notifications, IDisposable if you have resources that need to be released when you dispose of the view model (also allowing you to use the “using” statement), IDataErrorInfo optionally if you have extra data in the view model that needs to be validated.
If you’re using RIA services, you can mark the view models as .shared.cs so they are shared by the client also! I’ll write more on this soon.