I've been asked to research approaches to deal with an app we're supposed to be building. This app, hypothetically a Windows form written in C#, will issue commands directly to the server if it's connected, but if the app is offline, the state must be maintained as if it was connected and then sync up and issue data changes/commands to the server once it is connected.

I'm not sure where to start looking. This is something akin to Google Gears, but I don't think I have that option if we go a Winform route (which looks likely, given that there are other functions the application needs that a web app couldn't perform). Is the Microsoft Sync framework a viable option? Does Silverlight do anything like this? Any other options? I've Googled around a bit but would like the community input on what's best given the scenario.

+6  A: 

The Microsoft Sync Framework definitely supports the scenario you describe, although I would say that it's fairly complicated to get it working.

One thing to understand about the Sync Framework is that it's really two quite distinct frameworks shipping in the same package:

  • Sync Framework
  • ADO.NET Sync services v. 2

The ADO.NET Sync services are by far the easiest to set up, but they are constrained to synchronizing two relational data stores (although you can set up a web service as a remote facade between the two).

The core Sync Framework has no such limitations, but is far more complex to implement. When I used it about six months ago, I found that the best source to learn from was the SDK, and particularly the File/Folder sync sample code.

As far as I could tell, there was little to no sharing of code and types between the two 'frameworks', so you will have to pick one or the other.

In either case, there are no constraints on how you host the sync code, so Windows Forms is just one option among many.

Mark Seemann
Very informative, thank you.
+1  A: 

If I understand correctly, this doesn't sound like an actual data synchronization issue to me where you want to keep two databases in sync. it sounds more like you want a reliable mechanism for a client to call functions on a server in an environment where the connection is unstable, and if the connection is not present at the time, you want the function called as soon as the connection is back up.

If my understanding is right, this is one option. if not, this will probably not be helpful.

This is a very short answer to an in-depth problem, but we had a similar situation and this is how we handled it.

We have a client application that needs to monitor some data on a PC in a store. When certain events happen, this client application needs to update our server in the corporate offices, preferably Real-Time. However, the connection is not 100% reliable, so we needed a similar mechanism.

We solved this by trying to write to the server via a web service. If there is an error calling the web service, the command is serialized as an XML file in a folder named "waiting to upload".

We have a routine running in our client app on a timer set for every n minutes. When the timer elapses, it checks for XML files in this folder. If found, it attempts to call the web service using the information saved in the file, and so on until it is successful. Upon a successful call, the XML file is deleted.

It sounds hack-ish, but it was simple to code and has worked flawlessly for five years now. It's actually been our most trouble-free application all-around and we've implemented the pattern elsewhere successfully

David Stratton
Correct interpretation, yep. I was thinking of using MSMQ so that it's a fire-and-forget method that will keep trying until it gets there, but it's essentially the same thing as your approach. Thank you!
MSMQ is a good choice, too. We didn't use it because we didn't want to have to set it up on all of our clients, and the approach we took involved no extra steps for the installation team and administrators, although it did take extra steps in the development team. But if MSMQ will work for you, then I'd say that's a very good option.
David Stratton