I've moved to something a bit simpler that, from initial tests anyways, appears to work. Does this seem reasonable though (I think it assumes that the UIInvoker class itself is created on the UI thread):
public class UIInvoker : DisposableBase { private Activity m_activity = new Activity(); public void Invoke(Delegate method) { m_activity.RunOnUiThread(delegate { method.DynamicInvoke(null); }); } public void BeginInvoke(Delegate method) { ThreadPool.QueueUserWorkItem(delegate { m_activity.RunOnUiThread(delegate { method.DynamicInvoke(null); }); }); } public void Invoke(Delegate method, object[] @params) { m_activity.RunOnUiThread(delegate { method.DynamicInvoke(@params); }); } public void BeginInvoke(Delegate method, object[] @params) { ThreadPool.QueueUserWorkItem(delegate { m_activity.RunOnUiThread(delegate { method.DynamicInvoke(@params); }); }); } } > -----Original Message----- > From: monodroid-boun...@lists.ximian.com [mailto:monodroid- > boun...@lists.ximian.com] On Behalf Of Chris Tacke > Sent: Monday, February 20, 2012 10:18 AM > To: Discussions related to Mono for Android > Subject: [mono-android] Analog for Control.[Begin]Invoke > > 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 _______________________________________________ Monodroid mailing list Monodroid@lists.ximian.com UNSUBSCRIBE INFORMATION: http://lists.ximian.com/mailman/listinfo/monodroid