Multi-Threading HowTo

Topics: Actions and Control Logic, iOS, Performance
Oct 7, 2013 at 1:20 PM
Hello guys,

I was wondering if someone could point me to a resource describing how to deal with multiple threads. Coming from iOS app and cocos-ios development I'm used to work with gcd to trigger ui updates on the main thread.

I haven't found anything googling for monogame or xna and multi-threading.

My current issue is that I'm having a timer which triggers audio events (I need them to be pretty accurate because it's a rhythm app and jitter > 3 - 5ms would be already pretty bad).

I thought I could also use this timer to trigger UI changes (move a playhead). Question is how to do it... Was thinking about having a synchronised collection that I update from the audio thread and read from the ccnode in Update() but this polling solution feels a little awkward.

Is there any performOnMainThread thingy in monogame / cocos2d-xna ?
Oct 10, 2013 at 8:06 PM
As one can probably see from the question I'm new to C# ....

This seems to do the trick but I'm still in doubt since it seems to be too easy. And why would it be missing ...
    public class UIThread
    {
        private static UIThread _instance;

        public static UIThread SharedInstance
        { 
            get { return _instance; }
        }

        // must be called from the main thread
        public static void Init()
        {
            _instance = new UIThread();
        }

        TaskScheduler _taskScheduler;

        private UIThread()
        {
            _taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }

        public void Run(Action action)
        {
            new Task(action).RunSynchronously(_taskScheduler);
        }
    }

UIThread.SharedInstance.Run(() => {
// stuff that need to run on the main thread
});
Coordinator
Dec 7, 2013 at 6:08 PM
hello,

You should use the recently added CCTask to do async operations. We have programmed it to work with the many platforms that we support.
Dec 11, 2013 at 3:23 PM
Thanks!

It doesn't fit my use case at hand since I don't want to fire off an async task.

I'm doing an audio app and have a second scheduler running that is triggering audio events at a higher rate than the 14ms from CCScheduler. I could try to get along with CCScheduler and quantise but the ear is pretty sensitive and you hear when a beat 'jitters'.

But I guess that the right way to do it is to call ScheduleSelector with the lambda that i want to run on the ui thread.
Dec 11, 2013 at 3:38 PM
Hm - or maybe - since this looks like a rather expensive thing for a one shot 'do it on the next frame' thing I could also register component that would keep a synchronised list of actions that it will perform on the next frame...

But maybe this is just premature optimisation for a thing that is only called a couple of times per second.
Coordinator
Dec 13, 2013 at 2:29 AM
So you fire a task at the start and don't end the task. Just keep it handy and run your own timer/scheduler.

Just remember that on WP8 the audio runs on the UI thread. No matter your threading model, it will always sync on the UI thread.

Other platforms may also do the same thing. Mobile devices don't have high performance audio hardware so don't expect miracles with $30 audio chips. ;)