Hello, Great contribution.
I have added the link in the resources section ( http://www.monobjc.net/index.php?page=resources). Regards, Laurent Etiemble. 2009/12/24 Oscar Blasco <oblasco...@gmail.com> > I have uploaded to my blog ( > http://traxnet.wordpress.com/2009/12/24/synchronizationcotext-for-cocoamonobjc/) > the code of our implementation of a SynchronizationContext for > Cocoa/Monobjc. Please feel free to comment the implementation, correct it or > improve it too. > > > > If you feel like it is ok, we don’t mind if you publish the article or > the code directly on the Monobjc page or in whatever place you think could > be useful for others. > > > > Happy Christmas all, > > > > Oscar Blasco > Senior Software Developer > *Video Stream Networks, S.L.* > Telf. +34 96 5993670 > Fax. +34 96 5993673 > obla...@vsn.es > *www.vsn-tv.com* > > > > > > ------------------------------------------------ > > > > using System; > > using System.Collections.Generic; > > using System.Text; > > using System.Threading; > > using Monobjc.Cocoa; > > using Monobjc; > > > > namespace vsn.MacOSXComponents.Threading > > { > > [ObjectiveCClass] > > public class SyncObject : NSObject > > { > > private SendOrPostCallback m_Callback; > > private Object m_State; > > > > public delegate void DeregisterDelegate(SyncObject sync_object); > > #if USE_SYNCOBJS_DICTIONARY > > private DeregisterDelegate m_DeregisterDelegate; > > #endif > > > > public static readonly Class SyncObjectClass = > Class.GetClassFromType(typeof(SyncObject)); > > > > /// > > /// Initializes a new instance of the class. > > /// > > public SyncObject() { } > > > > /// > > /// Initializes a new instance of the class. > > /// > > /// > > > > public SyncObject(IntPtr nativePointer) > > : base(nativePointer) { } > > > > public override void Dispose() > > { > > // This is here for testing purpouses > > //Console.Write("Disposing SyncObject"); > > base.Dispose(); > > } > > > > /// > > /// initializes the synchronization object with the given call back > and object state > > /// > > /// callback > > /// state > > /// if true, the current thread waits until the operation is > performed > > /// > > > > public void Initialize(SendOrPostCallback d, Object state, bool > wait, DeregisterDelegate dereg_delegate) > > { > > m_Callback = d; > > m_State = state; > > #if USE_SYNCOBJS_DICTIONARY > > m_DeregisterDelegate = dereg_delegate; > > #endif > > > > // Call the NSObject's performSelector method from csharp code > > > PerformSelectorOnMainThreadWithObjectWaitUntilDone(ObjectiveCRuntime.Selector("bridgedCallback:"), > this, wait); > > } > > > > /// > > /// This is our callback which is invoked by the main thread's > runloop > > /// > > [ObjectiveCMessage("bridgedCallback:")] > > public void BridgedCallback(NSObject param) > > { > > // Invoke the true callback > > m_Callback(m_State); > > > > #if USE_SYNCOBJS_DICTIONARY > > // Un register this object from our cache > > if (m_DeregisterDelegate != null) > > m_DeregisterDelegate(this); > > #endif > > > > // This region is unsafe as we are not protected against > the GC. Monobjc > > // has a cached reference to this object so shouldn't be a > problem but > > // could be a problem if the implementation changes. > > // Consider using a CER > > // GC.Collect(); // Testing > > > > // Mark this object for deletion by an AutoreleasePool > > this.Autorelease(); > > } > > } > > > > /// > > /// Cocoa's SynchronizationContext implementation > > /// > > /// Only Post and Send methods are implemented > > /// > > public class CocoaRunLoopSynchronizationContext : > SynchronizationContext > > { > > private Dictionary m_SyncObjectsDictionary; > > private readonly object m_lock = null; > > > > /// > > /// Default constructor > > /// > > public CocoaRunLoopSynchronizationContext() > > : base() > > { > > m_SyncObjectsDictionary = new Dictionary(); > > m_lock = new object(); > > } > > > > public override void Post(SendOrPostCallback d, Object state) > > { > > SyncObject sync = new SyncObject(); > > #if USE_SYNCOBJS_DICTIONARY > > lock(m_lock) > > m_SyncObjectsDictionary.Add(sync.GetHashCode(), sync); > > #endif > > sync.Initialize(d, state, false, DeregisterSyncObject); > > > > } > > > > public override void Send(SendOrPostCallback d, Object state) > > { > > SyncObject sync = new SyncObject(); > > #if USE_SYNCOBJS_DICTIONARY > > lock (m_lock) > > m_SyncObjectsDictionary.Add(sync.GetHashCode(), sync); > > #endif > > sync.Initialize(d, state, true, DeregisterSyncObject); > > } > > > > /// > > /// Called by SyncObject to remove itself from the dictionary so > that no reference is held > > /// > > /// > > target object to unregister > > private void DeregisterSyncObject(SyncObject sync_object) > > { > > #if USE_SYNCOBJS_DICTIONARY > > lock (m_lock) > > m_SyncObjectsDictionary.Remove(sync_object.GetHashCode()); > > #endif > > } > > } > > } > > > > > > >