I'm working on this Silverlight 3.0 Project that is completely filled with Async Calls to a Web Service. At the Main Page it fetches some needed dat开发者_JAVA技巧a in order for the application to work correctly using 3 Async Calls. Right now the application does not disable any controls while executing those calls meaning a user can interact with it without that needed data. I need to disable the whole grid and only after all 3 Async calls are finished then and only then enable the grid.
What's the best practice for doing this.
These are my calls:
client.GetAllAsync();
client.GetAllCompleted += new EventHandler<GetAllCompletedEventArgs>(client_GetAllCompleted);
client.GetActualAsync();
client.GetActualCompleted += new EventHandler<GetActualCompletedEventArgs>(client_GetActualCompleted);
client.GetSomeAsync();
client.GetSomeCompleted += new EventHandler<GetSomeCompletedEventArgs>(client_GetSomeCompleted);
Seems lot a lot of work just to queue some user interactivity.
I typically provide an application-wide interface:
public interface IAppGlobalState
{
void BeginAsync();
void EndAsync();
}
In the implementation, I'll do this:
public partial class MainShell : UserControl, IAppGlobalState
{
private int _queue;
private object _mutex = new Object();
public void BeginASync()
{
Monitor.Enter(_mutex);
if (_queue++ == 0)
{
VisualStateManager.GoToState(this, "BusyState", true);
}
Monitor.Exit(_mutex);
}
public void EndAsync()
{
Monitor.Enter(_mutex);
if (--_queue == 0)
{
VisualStateManager.GoToState(this, "IdleState", true);
}
Monitor.Exit(_mutex);
}
}
Of course if you have heavy multi-threading then you'll use Interlocked on those but most of the time you'll be invoking it from the same thread. Then, you simply do:
GlobalState.BeginAsync();
client.FirstAsyncCall();
GlobalState.BeginAsync();
client.FirstAsyncCall();
And then on the return, just:
GlobalState.EndAsync();
If you have nested calls, no problem, this method unwinds them.
- Make a unit of work item in your silverlight
- This UOW raises an event when finished
- Bind that event to your GUI code
- Use signaling or a simple counter in your unit of work to raise the 'finished' event.
精彩评论