Thursday 15 December 2011

ScheduledAgent on WP7 and Asynchronous Events

While working on my LiveTiles, I’ve had a few suggestions that I should wait for an event to occur on loading images.  That’s actually not the problem from what I can tell, but it raised an interesting question.

Let’s say that that I implement my OnInvoke like this:

protected override void OnInvoke(ScheduledTask task)
{
MyEventRaisingObject obj = new MyEventRaisingObject();
obj.SomeAsynchronouslyRaisedEvent += (sender, e) =>
{
// do some work to handle the event, and update our tile
// for example, fetch an xml feed asynchronously
}
NotifyComplete();
}


It looks to me like the OnInvoke will return before my event gets a chance to execute, or in any case I’ll hit my NotifyComplete call.

 

How does one effectively spin until an event has been raised without blocking the thread the object was created on?  Sure I can do this:

 


AutoResetEvent ev1 = new AutoResetEvent(false);
AutoResetEvent ev2 = new AutoResetEvent(false);

...

WaitHandle.WaitAll(new WaitHandle[] { ev1, ev2});

But won’t that block the thread we’re on?

-- update 16 dec --


Don’t even think about using the AutoResetEvent trick above. 


I tried it to wait for my images to be loaded into a BitmapSource, but it seems that the load is done on the UI thread, and as a result, I block the thread waiting for an event to be raised to signal my AutoReset, so that the event can never be raised.

1 comment:

  1. http://stackoverflow.com/questions/7058638/how-is-async-network-i-o-handled-with-a-wp7-scheduled-task

    It turns out, the end of OnInvoke isn't the end of your objects lifetime, even though that doesn't appear to be documented anywhere officially at the time of writing.

    You can go away and do what you like: Schedule callbacks, wire up event handlers, etc. NotifyComplete() appears to indicate that you're done to the scheduler, so it can (presumably) drop it's reference to you and reschedule.

    ReplyDelete