Skip to content

Instantly share code, notes, and snippets.

@JakubNei
Last active December 29, 2024 10:46

Revisions

  1. @aeroson aeroson revised this gist Jul 13, 2017. 2 changed files with 16 additions and 17 deletions.
    29 changes: 14 additions & 15 deletions UnitySynchronizeInvoke.cs → DeferredSynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -1,35 +1,34 @@
    /*
    Implementation of ISynchronizeInvoke for Unity3D game engine.
    Can be used to invoke anything on main Unity thread.
    ISynchronizeInvoke is used extensively in .NET forms, it's is elegant and quite useful in Unity as well.
    I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingObject.
    Implementation of ISynchronizeInvoke for Unity3D game engine.
    Can be used to invoke anything on main Unity thread.
    ISynchronizeInvoke is used extensively in .NET forms, it's is elegant and quite useful in Unity as well.
    I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingObject.
    help from: http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e631
    help from: http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e631
    license: WTFPL (http://www.wtfpl.net/)
    author: aeroson
    version: aeroson 2017-07-13 (author yyyy-MM-dd)
    license: WTFPL (http://www.wtfpl.net/)
    */

    using System.Threading;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System;
    using System.Reflection;

    public class UnitySynchronizeInvoke : ISynchronizeInvoke
    public class DeferredSynchronizeInvoke : ISynchronizeInvoke
    {
    private Queue<UnityAsyncResult> toExecute = new Queue<UnityAsyncResult>();
    private Queue<AsyncResult> toExecute = new Queue<AsyncResult>();
    private Thread mainThread;
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }

    public UnitySynchronizeInvoke()
    public DeferredSynchronizeInvoke()
    {
    mainThread = Thread.CurrentThread;
    }
    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
    var asyncResult = new UnityAsyncResult()
    var asyncResult = new AsyncResult()
    {
    method = method,
    args = args,
    @@ -77,7 +76,7 @@ public void ProcessQueue()
    "(created on thread id: " + mainThread.ManagedThreadId + ", called from thread id: " + Thread.CurrentThread.ManagedThreadId
    );

    UnityAsyncResult data = null;
    AsyncResult data = null;
    while (true)
    {
    lock (toExecute)
    @@ -91,7 +90,7 @@ public void ProcessQueue()
    }
    }

    private class UnityAsyncResult : IAsyncResult
    private class AsyncResult : IAsyncResult
    {
    public Delegate method;
    public object[] args;
    4 changes: 2 additions & 2 deletions UnitySynchronizeInvokeExample.cs
    Original file line number Diff line number Diff line change
    @@ -3,11 +3,11 @@

    public class UnitySynchronizeInvokeExample : MonoBehaviour
    {
    private UnitySynchronizeInvoke synchronizeInvoke;
    private DeferredSynchronizeInvoke synchronizeInvoke;

    private void Start()
    {
    synchronizeInvoke = new UnitySynchronizeInvoke();
    synchronizeInvoke = new DeferredSynchronizeInvoke();
    new Thread(ThreadMain).Start();
    }
    private void ThreadMain()
  2. @aeroson aeroson revised this gist Jul 13, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -15,6 +15,7 @@ I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingO
    using System.ComponentModel;
    using System.Collections.Generic;
    using System;
    using System.Reflection;

    public class UnitySynchronizeInvoke : ISynchronizeInvoke
    {
    @@ -71,7 +72,10 @@ public object Invoke(Delegate method, object[] args)
    public void ProcessQueue()
    {
    if (Thread.CurrentThread != mainThread)
    throw new Exception("Must be called from the same thread it was created on");
    throw new Exception(
    "must be called from the same thread it was created on " +
    "(created on thread id: " + mainThread.ManagedThreadId + ", called from thread id: " + Thread.CurrentThread.ManagedThreadId
    );

    UnityAsyncResult data = null;
    while (true)
  3. @aeroson aeroson revised this gist Jul 10, 2017. 1 changed file with 23 additions and 10 deletions.
    33 changes: 23 additions & 10 deletions UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingO

    public class UnitySynchronizeInvoke : ISynchronizeInvoke
    {
    private Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
    private Queue<UnityAsyncResult> toExecute = new Queue<UnityAsyncResult>();
    private Thread mainThread;
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }

    @@ -36,8 +36,16 @@ public IAsyncResult BeginInvoke(Delegate method, object[] args)
    manualResetEvent = new ManualResetEvent(false),
    };

    lock (fifoToExecute)
    fifoToExecute.Enqueue(asyncResult);
    if (InvokeRequired)
    {
    lock (toExecute)
    toExecute.Enqueue(asyncResult);
    }
    else
    {
    asyncResult.Invoke();
    asyncResult.CompletedSynchronously = true;
    }

    return asyncResult;
    }
    @@ -68,16 +76,14 @@ public void ProcessQueue()
    UnityAsyncResult data = null;
    while (true)
    {
    lock (fifoToExecute)
    lock (toExecute)
    {
    if (fifoToExecute.Count == 0)
    if (toExecute.Count == 0)
    break;
    data = fifoToExecute.Dequeue();
    data = toExecute.Dequeue();
    }

    data.AsyncState = Invoke(data.method, data.args);
    data.manualResetEvent.Set();
    data.IsCompleted = true;
    data.Invoke();
    }
    }

    @@ -89,6 +95,13 @@ private class UnityAsyncResult : IAsyncResult
    public WaitHandle AsyncWaitHandle { get { return manualResetEvent; } }
    public ManualResetEvent manualResetEvent;
    public object AsyncState { get; set; }
    public bool CompletedSynchronously { get { return IsCompleted; } }
    public bool CompletedSynchronously { get; set; }

    public void Invoke()
    {
    AsyncState = method.DynamicInvoke(args);
    IsCompleted = true;
    manualResetEvent.Set();
    }
    }
    }
  4. @aeroson aeroson revised this gist Jul 10, 2017. 2 changed files with 94 additions and 96 deletions.
    143 changes: 71 additions & 72 deletions UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -11,85 +11,84 @@ I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingO
    author: aeroson
    */

    using System.Collections;
    using System.Threading;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Reflection;
    using System;

    public class UnitySynchronizeInvoke : ISynchronizeInvoke
    {
    Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
    Thread mainThread;
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }
    private Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
    private Thread mainThread;
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }

    public UnitySynchronizeInvoke()
    {
    mainThread = Thread.CurrentThread;
    }
    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
    var asyncResult = new UnityAsyncResult()
    {
    method = method,
    args = args,
    IsCompleted = false,
    AsyncWaitHandle = new ManualResetEvent(false),
    };
    lock (fifoToExecute)
    {
    fifoToExecute.Enqueue(asyncResult);
    }
    return asyncResult;
    }
    public object EndInvoke(IAsyncResult result)
    {
    if (!result.IsCompleted)
    {
    result.AsyncWaitHandle.WaitOne();
    }
    return result.AsyncState;
    }
    public object Invoke(Delegate method, object[] args) {
    if (InvokeRequired)
    {
    var asyncResult = BeginInvoke(method, args);
    return EndInvoke(asyncResult);
    }
    else
    {
    return method.DynamicInvoke(args);
    }
    }
    public void ProcessQueue()
    {
    if (Thread.CurrentThread != mainThread)
    {
    throw new Exception("Must be called from the same thread it was created on");
    }
    bool loop = true;
    UnityAsyncResult data = null;
    while (loop)
    {
    lock (fifoToExecute)
    {
    loop = fifoToExecute.Count > 0;
    if (!loop) break;
    data = fifoToExecute.Dequeue();
    }
    public UnitySynchronizeInvoke()
    {
    mainThread = Thread.CurrentThread;
    }
    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
    var asyncResult = new UnityAsyncResult()
    {
    method = method,
    args = args,
    IsCompleted = false,
    manualResetEvent = new ManualResetEvent(false),
    };

    data.AsyncState = Invoke(data.method, data.args);
    data.IsCompleted = true;
    }
    }
    class UnityAsyncResult : IAsyncResult
    {
    public Delegate method;
    public object[] args;
    public bool IsCompleted { get; set; }
    public WaitHandle AsyncWaitHandle { get; internal set; }
    public object AsyncState { get; set; }
    public bool CompletedSynchronously { get { return IsCompleted; } }
    }
    lock (fifoToExecute)
    fifoToExecute.Enqueue(asyncResult);

    return asyncResult;
    }
    public object EndInvoke(IAsyncResult result)
    {
    if (!result.IsCompleted)
    result.AsyncWaitHandle.WaitOne();

    return result.AsyncState;
    }
    public object Invoke(Delegate method, object[] args)
    {
    if (InvokeRequired)
    {
    var asyncResult = BeginInvoke(method, args);
    return EndInvoke(asyncResult);
    }
    else
    {
    return method.DynamicInvoke(args);
    }
    }
    public void ProcessQueue()
    {
    if (Thread.CurrentThread != mainThread)
    throw new Exception("Must be called from the same thread it was created on");

    UnityAsyncResult data = null;
    while (true)
    {
    lock (fifoToExecute)
    {
    if (fifoToExecute.Count == 0)
    break;
    data = fifoToExecute.Dequeue();
    }

    data.AsyncState = Invoke(data.method, data.args);
    data.manualResetEvent.Set();
    data.IsCompleted = true;
    }
    }

    private class UnityAsyncResult : IAsyncResult
    {
    public Delegate method;
    public object[] args;
    public bool IsCompleted { get; set; }
    public WaitHandle AsyncWaitHandle { get { return manualResetEvent; } }
    public ManualResetEvent manualResetEvent;
    public object AsyncState { get; set; }
    public bool CompletedSynchronously { get { return IsCompleted; } }
    }
    }
    47 changes: 23 additions & 24 deletions UnitySynchronizeInvokeExample.cs
    Original file line number Diff line number Diff line change
    @@ -3,29 +3,28 @@

    public class UnitySynchronizeInvokeExample : MonoBehaviour
    {
    private UnitySynchronizeInvoke synchronizeInvoke;

    UnitySynchronizeInvoke synchronizeInvoke;

    void Start()
    {
    synchronizeInvoke = new UnitySynchronizeInvoke();
    (new Thread(ThreadMain)).Start();
    }
    void ThreadMain()
    {
    while (true)
    {
    var retObj = synchronizeInvoke.Invoke((System.Func<string>)(() =>
    {
    this.transform.localScale = Vector3.one * Random.Range(1.0f, 10.0f);
    return this.gameObject.name;
    }), null);
    Debug.Log("Waited for the end of synchronizeInvoke and it synchronously returned me: " + (retObj as string));
    Thread.Sleep(1 * 1000);
    }
    }
    void Update()
    {
    synchronizeInvoke.ProcessQueue();
    }
    private void Start()
    {
    synchronizeInvoke = new UnitySynchronizeInvoke();
    new Thread(ThreadMain).Start();
    }
    private void ThreadMain()
    {
    while (true)
    {
    var retObj = synchronizeInvoke.Invoke((System.Func<string>)(() =>
    {
    this.transform.localScale = Vector3.one * Random.Range(1.0f, 10.0f);
    return this.gameObject.name;
    }), null);
    Debug.Log("Waited for the end of synchronizeInvoke and it synchronously returned me: " + (retObj as string));
    Thread.Sleep(1 * 1000);
    }
    }
    private void Update()
    {
    synchronizeInvoke.ProcessQueue();
    }
    }
  5. @aeroson aeroson revised this gist Jun 10, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@ I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingO
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e631
    license: WTFPL (http://www.wtfpl.net/)
    contact: aeroson (theaeroson @gmail.com)
    author: aeroson
    */

    using System.Collections;
  6. JakubNei revised this gist Aug 18, 2015. 1 changed file with 14 additions and 17 deletions.
    31 changes: 14 additions & 17 deletions UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,14 @@
    /*
    Implementation of ISynchronizeInvoke for Unity3D game engine.
    Can be used to invoke anything on main Unity thread.
    ISynchronizeInvoke is used extensively in .NET forms it's design seems elegant and probably quite useful in Unity as well.
    I implemented it so i can use it with System.IO.FileSystemWatcher
    ISynchronizeInvoke is used extensively in .NET forms, it's is elegant and quite useful in Unity as well.
    I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingObject.
    help from: http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e631
    help from http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    license: WTFPL (http://www.wtfpl.net/)
    contact: aeroson (theaeroson @gmail.com)
    */

    using System.Collections;
    @@ -18,17 +22,12 @@ public class UnitySynchronizeInvoke : ISynchronizeInvoke
    {
    Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
    Thread mainThread;
    public bool InvokeRequired
    {
    get
    {
    return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId;
    }
    }
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }

    public UnitySynchronizeInvoke()
    {
    mainThread = Thread.CurrentThread;
    }
    }
    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
    var asyncResult = new UnityAsyncResult()
    @@ -52,18 +51,17 @@ public object EndInvoke(IAsyncResult result)
    }
    return result.AsyncState;
    }
    public object Invoke(Delegate method, object[] args)
    {
    public object Invoke(Delegate method, object[] args) {
    if (InvokeRequired)
    {
    {
    var asyncResult = BeginInvoke(method, args);
    return EndInvoke(asyncResult);
    }
    else
    {
    return method.DynamicInvoke(args);
    }
    }
    }
    public void ProcessQueue()
    {
    if (Thread.CurrentThread != mainThread)
    @@ -83,9 +81,8 @@ public void ProcessQueue()

    data.AsyncState = Invoke(data.method, data.args);
    data.IsCompleted = true;
    (data.AsyncWaitHandle as EventWaitHandle).Set();
    }
    }
    }
    class UnityAsyncResult : IAsyncResult
    {
    public Delegate method;
  7. JakubNei revised this gist Jul 18, 2015. 3 changed files with 38 additions and 38 deletions.
    11 changes: 7 additions & 4 deletions UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -18,12 +18,17 @@ public class UnitySynchronizeInvoke : ISynchronizeInvoke
    {
    Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
    Thread mainThread;
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }
    public bool InvokeRequired
    {
    get
    {
    return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId;
    }
    }
    public UnitySynchronizeInvoke()
    {
    mainThread = Thread.CurrentThread;
    }

    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
    var asyncResult = new UnityAsyncResult()
    @@ -59,7 +64,6 @@ public object Invoke(Delegate method, object[] args)
    return method.DynamicInvoke(args);
    }
    }

    public void ProcessQueue()
    {
    if (Thread.CurrentThread != mainThread)
    @@ -91,5 +95,4 @@ class UnityAsyncResult : IAsyncResult
    public object AsyncState { get; set; }
    public bool CompletedSynchronously { get { return IsCompleted; } }
    }

    }
    31 changes: 31 additions & 0 deletions UnitySynchronizeInvokeExample.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    using UnityEngine;
    using System.Threading;

    public class UnitySynchronizeInvokeExample : MonoBehaviour
    {

    UnitySynchronizeInvoke synchronizeInvoke;

    void Start()
    {
    synchronizeInvoke = new UnitySynchronizeInvoke();
    (new Thread(ThreadMain)).Start();
    }
    void ThreadMain()
    {
    while (true)
    {
    var retObj = synchronizeInvoke.Invoke((System.Func<string>)(() =>
    {
    this.transform.localScale = Vector3.one * Random.Range(1.0f, 10.0f);
    return this.gameObject.name;
    }), null);
    Debug.Log("Waited for the end of synchronizeInvoke and it synchronously returned me: " + (retObj as string));
    Thread.Sleep(1 * 1000);
    }
    }
    void Update()
    {
    synchronizeInvoke.ProcessQueue();
    }
    }
    34 changes: 0 additions & 34 deletions UnitySynchronizedInvokeExample.cs
    Original file line number Diff line number Diff line change
    @@ -1,34 +0,0 @@
    using UnityEngine;
    using System.Threading;

    public class UnitySynchronizedInvokeExample : MonoBehaviour
    {

    UnitySynchronizeInvoke synchronizedInvoke;

    void Start()
    {
    synchronizedInvoke = new UnitySynchronizeInvoke();
    (new Thread(ThreadMain)).Start();
    }

    void ThreadMain()
    {
    while (true)
    {
    var retObj = synchronizedInvoke.Invoke((System.Func<string>)(() =>
    {
    this.transform.localScale = Vector3.one * Random.Range(1.0f, 10.0f);
    return this.gameObject.name;
    }), null);
    Debug.Log("Waited for the end of synchronizedInvoke and it synchronously returned me: " + (retObj as string));
    Thread.Sleep(1 * 1000);
    }
    }

    void Update()
    {
    synchronizedInvoke.ProcessQueue();
    }

    }
  8. JakubNei revised this gist Jul 18, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion UnitySynchronizedInvokeExample.cs
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@ void ThreadMain()
    this.transform.localScale = Vector3.one * Random.Range(1.0f, 10.0f);
    return this.gameObject.name;
    }), null);
    Debug.Log("Waired for end the synchronizedInvoke and it synchronously returned me: " + (retObj as string));
    Debug.Log("Waited for the end of synchronizedInvoke and it synchronously returned me: " + (retObj as string));
    Thread.Sleep(1 * 1000);
    }
    }
  9. JakubNei revised this gist Jul 18, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    Can be used to invoke anything on main Unity thread.
    ISynchronizeInvoke is used extensively in .NET forms it's design seems elegant and probably quite useful in Unity as well.
    I implemented it so i can use it with System.IO.FileSystemWatcher
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e63
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e631
    help from http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    */

  10. JakubNei revised this gist Jul 18, 2015. 1 changed file with 8 additions and 3 deletions.
    11 changes: 8 additions & 3 deletions UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,11 @@
    // ISynchronizeInvoke is used extensively in .NET forms
    // its design seems elegant and probably quite useful in Unity as well
    // help from http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    /*
    Implementation of ISynchronizeInvoke for Unity3D game engine.
    Can be used to invoke anything on main Unity thread.
    ISynchronizeInvoke is used extensively in .NET forms it's design seems elegant and probably quite useful in Unity as well.
    I implemented it so i can use it with System.IO.FileSystemWatcher
    example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e63
    help from http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
    */

    using System.Collections;
    using System.Threading;
  11. JakubNei created this gist Jul 18, 2015.
    90 changes: 90 additions & 0 deletions UnitySynchronizeInvoke.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    // ISynchronizeInvoke is used extensively in .NET forms
    // its design seems elegant and probably quite useful in Unity as well
    // help from http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class

    using System.Collections;
    using System.Threading;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Reflection;
    using System;

    public class UnitySynchronizeInvoke : ISynchronizeInvoke
    {
    Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
    Thread mainThread;
    public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }
    public UnitySynchronizeInvoke()
    {
    mainThread = Thread.CurrentThread;
    }

    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
    var asyncResult = new UnityAsyncResult()
    {
    method = method,
    args = args,
    IsCompleted = false,
    AsyncWaitHandle = new ManualResetEvent(false),
    };
    lock (fifoToExecute)
    {
    fifoToExecute.Enqueue(asyncResult);
    }
    return asyncResult;
    }
    public object EndInvoke(IAsyncResult result)
    {
    if (!result.IsCompleted)
    {
    result.AsyncWaitHandle.WaitOne();
    }
    return result.AsyncState;
    }
    public object Invoke(Delegate method, object[] args)
    {
    if (InvokeRequired)
    {
    var asyncResult = BeginInvoke(method, args);
    return EndInvoke(asyncResult);
    }
    else
    {
    return method.DynamicInvoke(args);
    }
    }

    public void ProcessQueue()
    {
    if (Thread.CurrentThread != mainThread)
    {
    throw new Exception("Must be called from the same thread it was created on");
    }
    bool loop = true;
    UnityAsyncResult data = null;
    while (loop)
    {
    lock (fifoToExecute)
    {
    loop = fifoToExecute.Count > 0;
    if (!loop) break;
    data = fifoToExecute.Dequeue();
    }

    data.AsyncState = Invoke(data.method, data.args);
    data.IsCompleted = true;
    (data.AsyncWaitHandle as EventWaitHandle).Set();
    }
    }
    class UnityAsyncResult : IAsyncResult
    {
    public Delegate method;
    public object[] args;
    public bool IsCompleted { get; set; }
    public WaitHandle AsyncWaitHandle { get; internal set; }
    public object AsyncState { get; set; }
    public bool CompletedSynchronously { get { return IsCompleted; } }
    }

    }
    34 changes: 34 additions & 0 deletions UnitySynchronizedInvokeExample.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    using UnityEngine;
    using System.Threading;

    public class UnitySynchronizedInvokeExample : MonoBehaviour
    {

    UnitySynchronizeInvoke synchronizedInvoke;

    void Start()
    {
    synchronizedInvoke = new UnitySynchronizeInvoke();
    (new Thread(ThreadMain)).Start();
    }

    void ThreadMain()
    {
    while (true)
    {
    var retObj = synchronizedInvoke.Invoke((System.Func<string>)(() =>
    {
    this.transform.localScale = Vector3.one * Random.Range(1.0f, 10.0f);
    return this.gameObject.name;
    }), null);
    Debug.Log("Waired for end the synchronizedInvoke and it synchronously returned me: " + (retObj as string));
    Thread.Sleep(1 * 1000);
    }
    }

    void Update()
    {
    synchronizedInvoke.ProcessQueue();
    }

    }