I think I know the answer, but thought I'd ask the smart people.
It would be convenient if I could put up a MessageBox-like class like SyncSavePrompter.Show("You have unsaved edits, save now?") that prompts for saves to a FeatureLayer that has unsaved edits (FeatureLayer.HasEdits == true). This Show() method would call FeatureLayer.SaveEdits(), and SyncSavePrompter would handle both FeatureLayer.SaveEditsFailed and FeatureLayer.EndSaveEdits events. Show() would be modal - that is, block the user and method it is called from until the async save operation completes via either the SaveEditsFailed or EndSaveEdits event handler, then Show() would return a MessageBoxResult.
The usual way of synchronizing an async action, using a ManualResetEvent, calling WaitOne() to block the thread when the save starts, and Set() in the event handlers after the save completes or fails to unblock, does not work because the save, though async, seems to happen on the same thread - the WaitOne() blocks it, and we get nowhere. If I try to force the FeatureLayer.SaveEdits() to happen on another thread with ThreadPool.QueueUserWorkItem(), I get a invalid cross-thread action error. So either the save MUST happen on the main thread by some implementation detail inside the Silverlight API, and this idea is simply impossible, or I'm just too obtuse to do it right so far.
I'm prepared to do all this in an async way, but thought I'd ask anyway - it would be tidy 😉
Thanks, MC