You can use multithreading programming in applications that use Monobjc bridge without any restrictions: threads can be created by .NET or by the Objective-C runtime. There are some points to be aware when dealing with threads:

  • When launched, a Cocoa application starts as singlethreaded. It becomes multithreaded only when a call detachNewThreadSelector:toTarget:withObject: is made. Refer to Multithreading Programming Topics for more informations.
  • Multithreading programming can only be used if the application is multithreaded (from the Cocoa Point of View).
  • There is no link between a thread created by .NET and a thread created by the Objective-C runtime, because the .NET can map one ore more managed thread to native thread (it depends on the .NET runtime implementation).

Multithreaded mode

The Monobjc bridge provides necessary methods to ease the use of multithreading programming in your applications:

  • To know if the application is currently multithreaded or not, test the return value of NSThread.IsMultiThreaded method.
  • To switch an application in the multithreaded mode, call the NSThread.MakeMultiThreaded method. The call is blocked until the application reach the multithreaded mode. The call can be made several times, as it has no effect if the application is already multithreaded.

Below, the code to make an application multithreaded:

NSThread.MakeMultiThreaded();

Below, the code to create a new Objective-C thread, by detachment with a delegate.

NSThread.NSThreadRunner runner = delegate(Id argument)
                            {
                                // As we are running a new thread, a pool is required
                                NSAutoreleasePool pool = new NSAutoreleasePool();

                                NSString str = argument.CastTo<NSString>();
                                Console.WriteLine("String is " + str);

                                // Release the pool when the thread ends
                                pool.Release();
                            };

NSThread.DetachNewThreadSelectorToTargetWithObject(runner, (NSString) "The String");

Cross-thread calls and thread safety

One of the trickiest subject is when you want to mix thread and user interface. The vast majority of GUI frameworks don't support cross-thread calls when modifying a widget (there a lot of good reasons to do this and the big one is related to the message pump). .NET provides an handful interface named ISynchronizeInvoke to manage cross-thread calls. The Monobjc bridge provides an implementation of this interface when dealing with NSView subclasses. For more informations on how to use this interface, visit the MSDN website.