Friday, 24 February 2012

Asynchronous actions with RX

I was trying to come up with a syntactically tidy way to run some code in the ThreadPool.

Assume I have a function as follows that performs the work:

void PopulateIsolatedStorageList()
using (iso = IsolatedStorageFile.GetUserStoreForApplication())
string[] found = iso.ISO.GetDirectoryNames("Logs/*.*");
foreach (string s in found)
// do some time consuming processing here

First I attempted to create an Action delegate for the above, and then tried to do this:

Action b = this.PopulateIsolatedStorageList;
Observable.FromAsyncPattern(b.BeginInvoke, b.EndInvoke )().

This did not work.  First, PopulateIsolatedStorageList ended up with a null this pointer.

Secondly, it seemed to run on the main thread in any case.

A bit of lateral thinking required

What are my goals?

  1. I want to run my action on a worker thread.

  2. I want to perform some completed action on the UI thread (namely OnPropertyChanged).

Why not create an enumeration of things I want to get done on the worker thread then?

Action[] a = { PopulateIsolatedStorageList};
( action => action(),
      () => Deployment.Current.Dispatcher.BeginInvoke(() => UINotify() ));

Where UINotify() is the expression to perform on the main thread.


And surprisingly, it all works.

Update – It helps if you find the right method

Having searched some more I found another mechanism, which removes the need to create the array, and is probably the proper way to do it.

     _ => { },
() => Deployment.Current.Dispatcher.BeginInvoke(() => UINotify() ));

No comments:

Post a Comment