I'm porting the OpenNETCF IoC framework to Mono for Android. The code was almost compatible as-is, but there's one part that needs some Android-specific implementation.
The framework provides event aggregation, and one of the options for event subscribers is the context in which to run - either in the caller's context or the UI context. For the full and compact frameworks I simply used Control.Invoke (or BeginInvoke). Obviously that's not going to work in Mono for Android. What I'm looking for is the "best" way to achieve the thread migration. The code where this runs has no direct reference to any type of container object (Activity, etc). I've played with the idea of using an AsyncTask, but it didn't seem to behave the way I expected (though my understanding of the class could easily be wrong). I then wondered if maybe I should just create an Activity and use 'RunOnUiThread' instead. Basically what I'm trying to create is a generic "invoker" class that exposes Invoke and BeginInvoke and I'm looking for some sort of direction on what's going to be a reasonable mechanism to implement this. Here's my (failed) first attempt. public class UIInvoker { public void Invoke(Delegate method) { new UITask(false, method).Execute(); } public void BeginInvoke(Delegate method) { new UITask(true, method).Execute(); } public void Invoke(Delegate method, object[] @params) { new UITask(false, method, @params).Execute(); } public void BeginInvoke(Delegate method, object[] @params) { new UITask(true, method, @params).Execute(); } private class UITask : Android.OS.AsyncTask { Delegate m_method; object[] m_params; bool m_async; public UITask(bool async, Delegate method) : this(async, method, null) { } public UITask(bool async, Delegate method, object[] @params) { m_async = async; m_method = method; m_params = @params; } protected override void OnPreExecute() { if (!m_async) { m_method.DynamicInvoke(m_params); } } protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] @params) { return null; } protected override void OnPostExecute(Java.Lang.Object result) { if (m_async) { m_method.DynamicInvoke(m_params); } } } } When I run a quick test like this: new Thread(delegate { Thread.Sleep(1000); System.Diagnostics.Debug.WriteLine("Before invoke"); m_invoker.Invoke(new EventHandler(Invokee), new object[] { this, EventArgs.Empty }); Thread.Sleep(1000); System.Diagnostics.Debug.WriteLine("After invoke"); }) .Run(); Thread.Sleep(5000); ... private void Invokee(object sender, EventArgs a) { System.Diagnostics.Debug.WriteLine("invokee"); } I would expect the "invoke" to run last, after the UI thread unblocks, but that's not the behavior I'm seeing. ----------------- Chris Tacke President OpenNETCF Consulting, LLC _______________________________________________ Monodroid mailing list Monodroid@lists.ximian.com UNSUBSCRIBE INFORMATION: http://lists.ximian.com/mailman/listinfo/monodroid