├── .gitignore ├── Assets ├── Example.cs ├── Example.cs.meta ├── Threading.meta ├── Threading │ ├── Async.cs │ ├── Async.cs.meta │ ├── AsyncTask.cs │ ├── AsyncTask.cs.meta │ ├── Dispatcher.cs │ └── Dispatcher.cs.meta ├── main.unity └── main.unity.meta ├── LICENSE ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Unity 3 | ################# 4 | Temp/ 5 | Library/ 6 | AssetBundles/ 7 | 8 | # Not bin file 9 | *.bin 10 | 11 | 12 | ################# 13 | ## Mono 14 | ################# 15 | *.userprefs 16 | *.csproj 17 | *.DotSettings 18 | *.pidb 19 | *.sln 20 | *.unityproj 21 | 22 | ################# 23 | ## Eclipse 24 | ################# 25 | 26 | *.pydevproject 27 | .project 28 | .metadata 29 | bin/ 30 | tmp/ 31 | *.tmp 32 | *.bak 33 | *.swp 34 | *~.nib 35 | local.properties 36 | .classpath 37 | .settings/ 38 | .loadpath 39 | 40 | # External tool builders 41 | .externalToolBuilders/ 42 | 43 | # Locally stored "Eclipse launch configurations" 44 | *.launch 45 | 46 | # CDT-specific 47 | .cproject 48 | 49 | # PDT-specific 50 | .buildpath 51 | 52 | 53 | ################# 54 | ## Visual Studio 55 | ################# 56 | 57 | ## Ignore Visual Studio temporary files, build results, and 58 | ## files generated by popular Visual Studio add-ons. 59 | 60 | # User-specific files 61 | *.suo 62 | *.user 63 | *.sln.docstates 64 | 65 | # Build results 66 | 67 | [Dd]ebug/ 68 | [Rr]elease/ 69 | x64/ 70 | build/ 71 | [Bb]in/ 72 | [Oo]bj/ 73 | 74 | # MSTest test Results 75 | [Tt]est[Rr]esult*/ 76 | [Bb]uild[Ll]og.* 77 | 78 | *_i.c 79 | *_p.c 80 | *.ilk 81 | *.obj 82 | *.pch 83 | *.pdb 84 | *.pgc 85 | *.pgd 86 | *.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.log 99 | *.scc 100 | 101 | # Visual C++ cache files 102 | ipch/ 103 | *.aps 104 | *.ncb 105 | *.opensdf 106 | *.sdf 107 | *.cachefile 108 | 109 | # Visual Studio profiler 110 | *.psess 111 | *.vsp 112 | *.vspx 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | 121 | # TeamCity is a build add-in 122 | _TeamCity* 123 | 124 | # DotCover is a Code Coverage Tool 125 | *.dotCover 126 | 127 | # NCrunch 128 | *.ncrunch* 129 | .*crunch*.local.xml 130 | 131 | # Installshield output folder 132 | [Ee]xpress/ 133 | 134 | # DocProject is a documentation generator add-in 135 | DocProject/buildhelp/ 136 | DocProject/Help/*.HxT 137 | DocProject/Help/*.HxC 138 | DocProject/Help/*.hhc 139 | DocProject/Help/*.hhk 140 | DocProject/Help/*.hhp 141 | DocProject/Help/Html2 142 | DocProject/Help/html 143 | 144 | # Click-Once directory 145 | publish/ 146 | 147 | # Publish Web Output 148 | *.Publish.xml 149 | *.pubxml 150 | 151 | # NuGet Packages Directory 152 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 153 | #packages/ 154 | 155 | # Windows Azure Build Output 156 | csx 157 | *.build.csdef 158 | 159 | # Windows Store app package directory 160 | AppPackages/ 161 | 162 | # Others 163 | sql/ 164 | *.Cache 165 | ClientBin/ 166 | [Ss]tyle[Cc]op.* 167 | ~$* 168 | *~ 169 | *.dbmdl 170 | *.[Pp]ublish.xml 171 | *.pfx 172 | *.publishsettings 173 | 174 | # RIA/Silverlight projects 175 | Generated_Code/ 176 | 177 | # Backup & report files from converting an old project file to a newer 178 | # Visual Studio version. Backup files are not needed, because we have git ;-) 179 | _UpgradeReport_Files/ 180 | Backup*/ 181 | UpgradeLog*.XML 182 | UpgradeLog*.htm 183 | 184 | # SQL Server files 185 | App_Data/*.mdf 186 | App_Data/*.ldf 187 | 188 | ############# 189 | ## Windows detritus 190 | ############# 191 | 192 | # Windows image file caches 193 | Thumbs.db 194 | Thumbs.db.meta 195 | ehthumbs.db 196 | ehthumbs.db.meta 197 | *.Thumbs.db.meta 198 | *.ehthumbs.db.meta 199 | 200 | 201 | # Folder config file 202 | Desktop.ini 203 | 204 | # Recycle Bin used on file shares 205 | $RECYCLE.BIN/ 206 | 207 | # Mac crap 208 | .DS_Store 209 | 210 | 211 | ############# 212 | ## Python 213 | ############# 214 | 215 | *.py[co] 216 | 217 | # Packages 218 | *.egg 219 | *.egg-info 220 | dist/ 221 | build/ 222 | eggs/ 223 | parts/ 224 | var/ 225 | sdist/ 226 | develop-eggs/ 227 | .installed.cfg 228 | 229 | # Installer logs 230 | pip-log.txt 231 | 232 | # Unit test / coverage reports 233 | .coverage 234 | .tox 235 | 236 | #Translations 237 | *.mo 238 | 239 | #Mr Developer 240 | .mr.developer.cfg 241 | 242 | ###### 243 | # Not obj files in assets 244 | ###### 245 | !Assets/*.obj 246 | !Assets/**/*.obj 247 | 248 | ##### 249 | # Specific files 250 | ##### 251 | -------------------------------------------------------------------------------- /Assets/Example.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using Threading; 5 | using UnityEngine; 6 | 7 | public class Example : MonoBehaviour 8 | { 9 | private readonly Queue _actionQueue = new Queue(); 10 | public Queue ActionQueue 11 | { 12 | get 13 | { 14 | lock (Async.GetLock("ActionQueue")) 15 | { 16 | return _actionQueue; 17 | } 18 | } 19 | } 20 | 21 | void Start() 22 | { 23 | WaitAndReport(); 24 | WaitAndReportValue(); 25 | CalcAndReportRepeatedly(); 26 | CalcAndReportValueRepeatedly(); 27 | } 28 | 29 | private void WaitAndReport() 30 | { 31 | Async.Run(() => 32 | { 33 | Thread.Sleep(1000); 34 | }).ContinueInMainThread(() => 35 | { 36 | Debug.Log("Done waiting"); 37 | }); 38 | } 39 | 40 | private void WaitAndReportValue() 41 | { 42 | Async.Run(() => 43 | { 44 | Thread.Sleep(1000); 45 | return 10; 46 | }).ContinueInMainThread((result) => 47 | { 48 | Debug.Log("Done. Value is " + result); 49 | }); 50 | } 51 | 52 | private void CalcAndReportRepeatedly() 53 | { 54 | Async.RunInBackground("CalcAndReportRepeatedly", 1000, () => 55 | { 56 | long date1 = DateTime.UtcNow.Ticks; 57 | Thread.Sleep(50); 58 | long date2 = DateTime.UtcNow.Ticks; 59 | ActionQueue.Enqueue(() => 60 | { 61 | Debug.Log("date1: " + date1 + " + date2: " + date2 + " = " + (date1 + date2)); 62 | }); 63 | }).ContinueInMainThread(() => 64 | { 65 | Action action = ActionQueue.Dequeue(); 66 | action(); 67 | }); 68 | } 69 | 70 | private void CalcAndReportValueRepeatedly() 71 | { 72 | Async.RunInBackground("CalcAndReportValueRepeatedly", 1000, () => 73 | { 74 | long value = DateTime.UtcNow.Ticks; 75 | return value; 76 | }).ContinueInMainThread((result) => 77 | { 78 | DateTime dateTime = DateTime.FromBinary(result); 79 | Debug.Log("DateTime value: " + dateTime); 80 | }); 81 | } 82 | } -------------------------------------------------------------------------------- /Assets/Example.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 949b45c9fba10fa43966699c6e7dd993 3 | timeCreated: 1489831499 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Threading.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce8b35573b5180d45a2383987eb0ed01 3 | folderAsset: yes 4 | timeCreated: 1489823469 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Threading/Async.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Threading 5 | { 6 | public class Async 7 | { 8 | private static Dispatcher Dispatcher 9 | { 10 | get { return Dispatcher.Instance; } 11 | } 12 | 13 | private static readonly Dictionary Locks = new Dictionary(); 14 | 15 | public static AsyncTask Run(Action action) 16 | { 17 | AsyncTask asyncTask = new AsyncTask(action); 18 | Dispatcher.RegisterTask(asyncTask); 19 | return asyncTask; 20 | } 21 | 22 | public static AsyncTask Run(Func func) 23 | { 24 | AsyncTask asyncTask = new AsyncTask(func); 25 | Dispatcher.RegisterTask(asyncTask); 26 | return asyncTask; 27 | } 28 | 29 | public static AsyncTask RunInBackground(string taskName, int runFrequencyMs, Action action) 30 | { 31 | if (Dispatcher.HasBackgroundTask(taskName) == false) 32 | { 33 | AsyncTask asyncTask = new AsyncTask(action, runFrequencyMs); 34 | Dispatcher.RegisterBackgroundTask(taskName, asyncTask); 35 | return asyncTask; 36 | } 37 | return Dispatcher.GetBackgroundTask(taskName); 38 | } 39 | 40 | public static AsyncTask RunInBackground(string taskName, int runFrequencyMs, Func func) 41 | { 42 | if (Dispatcher.HasBackgroundTask(taskName) == false) 43 | { 44 | AsyncTask asyncTask = new AsyncTask(func, runFrequencyMs); 45 | Dispatcher.RegisterBackgroundTask(taskName, asyncTask); 46 | return asyncTask; 47 | } 48 | var genericAsyncTask = Dispatcher.GetBackgroundTask(taskName) as AsyncTask; 49 | if (genericAsyncTask == null) 50 | { 51 | throw new InvalidOperationException("Cannot find requested generic AsyncTask with name " + taskName); 52 | } 53 | return genericAsyncTask; 54 | } 55 | 56 | public static object GetLock(string key) 57 | { 58 | object lockObj; 59 | Locks.TryGetValue(key, out lockObj); 60 | 61 | if (lockObj == null) 62 | { 63 | lockObj = new object(); 64 | Locks.Add(key, lockObj); 65 | } 66 | 67 | return lockObj; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Assets/Threading/Async.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f1f3a24991097b43b397e5af5507523 3 | timeCreated: 1489831499 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Threading/AsyncTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace Threading 6 | { 7 | public class AsyncTask 8 | { 9 | public Thread Thread { get; protected set; } 10 | 11 | protected readonly object LockObject = new object(); 12 | private readonly Queue _callBackQueue; 13 | 14 | private Queue CallBackQueue 15 | { 16 | get 17 | { 18 | lock (LockObject) 19 | { 20 | return _callBackQueue; 21 | } 22 | } 23 | } 24 | 25 | protected AsyncTask() { } 26 | 27 | public AsyncTask(Action action) 28 | { 29 | Thread thread = new Thread(() => 30 | { 31 | action(); 32 | }); 33 | Thread = thread; 34 | Thread.Start(); 35 | } 36 | 37 | public AsyncTask(Action action, int runFrequencyMs) 38 | { 39 | _callBackQueue = new Queue(); 40 | Thread thread = new Thread(() => 41 | { 42 | while (true) 43 | { 44 | action(); 45 | CallBackQueue.Enqueue(action); 46 | Thread.Sleep(runFrequencyMs); 47 | } 48 | }); 49 | Thread = thread; 50 | Thread.Start(); 51 | } 52 | 53 | public bool IsFinished 54 | { 55 | get { return Thread.IsAlive == false; } 56 | } 57 | 58 | protected virtual bool IsBackgroundTask 59 | { 60 | get { return CallBackQueue != null; } 61 | } 62 | 63 | public void ContinueInMainThread(Action action) 64 | { 65 | _onTaskFinished = action; 66 | } 67 | 68 | private Action _onTaskFinished; 69 | public virtual void OnTaskFinished() 70 | { 71 | if (_onTaskFinished != null) 72 | { 73 | if (IsBackgroundTask) 74 | { 75 | while (CallBackQueue.Count > 0) 76 | { 77 | CallBackQueue.Dequeue(); 78 | _onTaskFinished(); 79 | } 80 | } 81 | else 82 | { 83 | _onTaskFinished(); 84 | } 85 | } 86 | } 87 | } 88 | 89 | public class AsyncTask : AsyncTask 90 | { 91 | public T Result { get; private set; } 92 | 93 | private readonly Queue _backgroundResults; 94 | 95 | private Queue BackgroundResults 96 | { 97 | get 98 | { 99 | lock (LockObject) 100 | { 101 | return _backgroundResults; 102 | } 103 | } 104 | } 105 | 106 | private Action _onTaskFinishedResult; 107 | 108 | protected override bool IsBackgroundTask 109 | { 110 | get { return BackgroundResults != null; } 111 | } 112 | 113 | public AsyncTask(Func func) 114 | { 115 | Thread thread = new Thread(() => 116 | { 117 | Result = func(); 118 | }); 119 | Thread = thread; 120 | Thread.Start(); 121 | } 122 | 123 | public AsyncTask(Func func, int runFrequencyMs) 124 | { 125 | _backgroundResults = new Queue(); 126 | Thread thread = new Thread(() => 127 | { 128 | while (true) 129 | { 130 | BackgroundResults.Enqueue(func()); 131 | Thread.Sleep(runFrequencyMs); 132 | } 133 | }); 134 | Thread = thread; 135 | Thread.Start(); 136 | } 137 | 138 | public void ContinueInMainThread(Action action) 139 | { 140 | _onTaskFinishedResult = action; 141 | } 142 | 143 | public override void OnTaskFinished() 144 | { 145 | if (_onTaskFinishedResult != null) 146 | { 147 | if (IsBackgroundTask) 148 | { 149 | while (BackgroundResults.Count > 0) 150 | { 151 | T result = BackgroundResults.Dequeue(); 152 | _onTaskFinishedResult(result); 153 | } 154 | } 155 | else 156 | { 157 | _onTaskFinishedResult(Result); 158 | } 159 | } 160 | else base.OnTaskFinished(); 161 | } 162 | } 163 | } -------------------------------------------------------------------------------- /Assets/Threading/AsyncTask.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12611abe08dd22c40914a1baf9656e67 3 | timeCreated: 1489831499 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Threading/Dispatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Threading 5 | { 6 | public class Dispatcher : MonoBehaviour 7 | { 8 | private static readonly HashSet ThreadedTasks = new HashSet(); 9 | private static readonly Dictionary BackgroundTasks = new Dictionary(); 10 | 11 | private static Dispatcher _instance; 12 | public static Dispatcher Instance 13 | { 14 | get 15 | { 16 | if (_instance == null) 17 | { 18 | var dispatcherObject = new GameObject("TheadDispatcher"); 19 | _instance = dispatcherObject.AddComponent(); 20 | DontDestroyOnLoad(dispatcherObject); 21 | } 22 | return _instance; 23 | } 24 | } 25 | 26 | private readonly List _deadTasks = new List(); 27 | private void Update() 28 | { 29 | _deadTasks.Clear(); 30 | foreach (AsyncTask threadedTask in ThreadedTasks) 31 | { 32 | if (threadedTask.IsFinished) 33 | { 34 | threadedTask.OnTaskFinished(); 35 | _deadTasks.Add(threadedTask); 36 | } 37 | } 38 | foreach (AsyncTask threadedTask in _deadTasks) 39 | { 40 | ThreadedTasks.Remove(threadedTask); 41 | } 42 | 43 | foreach (KeyValuePair backgroundTask in BackgroundTasks) 44 | { 45 | backgroundTask.Value.OnTaskFinished(); 46 | } 47 | } 48 | 49 | public void Reset() 50 | { 51 | foreach (AsyncTask threadedTask in ThreadedTasks) 52 | { 53 | threadedTask.Thread.Abort(); 54 | } 55 | ThreadedTasks.Clear(); 56 | 57 | foreach (KeyValuePair backgroundTask in BackgroundTasks) 58 | { 59 | backgroundTask.Value.Thread.Abort(); 60 | } 61 | BackgroundTasks.Clear(); 62 | } 63 | 64 | public void RegisterTask(AsyncTask asyncTask) 65 | { 66 | ThreadedTasks.Add(asyncTask); 67 | } 68 | 69 | public bool HasBackgroundTask(string taskName) 70 | { 71 | return BackgroundTasks.ContainsKey(taskName); 72 | } 73 | 74 | public AsyncTask GetBackgroundTask(string taskName) 75 | { 76 | AsyncTask asyncTask; 77 | BackgroundTasks.TryGetValue(taskName, out asyncTask); 78 | return asyncTask; 79 | } 80 | 81 | public void RegisterBackgroundTask(string taskName, AsyncTask asyncTask) 82 | { 83 | BackgroundTasks.Add(taskName, asyncTask); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Assets/Threading/Dispatcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83c2aba28354e32499270bb4e6d6c47a 3 | timeCreated: 1489823479 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/main.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/Assets/main.unity -------------------------------------------------------------------------------- /Assets/main.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 29b21a97a1f3c784db9b2db20a70a19f 3 | timeCreated: 1489819736 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Phuong Nguyen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.5.2f1 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuongfi91/unity-threading/49176226a62d63071d3aa1609c5220c03d8cc045/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unity-threading 2 | Simple implementation to easily perform multithreaded asynchronous operations in Unity3D. 3 | All feedbacks, contributions are very much welcomed. 4 | 5 | # Example usages 6 | 7 | ### Wait for a task to finish executing before returning back to main Unity thread 8 | 9 | private void WaitAndReport() 10 | { 11 | Async.Run(() => 12 | { 13 | Thread.Sleep(1000); 14 | }).ContinueInMainThread(() => 15 | { 16 | Debug.Log("Done waiting"); 17 | }); 18 | } 19 | 20 | ### Wait for a task to finish executing before returning a value back to main Unity thread 21 | 22 | private void WaitAndReportValue() 23 | { 24 | Async.Run(() => 25 | { 26 | Thread.Sleep(1000); 27 | return 10; 28 | }).ContinueInMainThread((result) => 29 | { 30 | Debug.Log("Done. Value is " + result); 31 | }); 32 | } 33 | 34 | ### Perform a background operation then return the value to main thread once done. The background task is repeated every second (1000 ms) 35 | 36 | private void CalcAndReportValueRepeatedly() 37 | { 38 | Async.RunInBackground("CalcAndReportValueRepeatedly", 1000, () => 39 | { 40 | long value = DateTime.UtcNow.Ticks; 41 | return value; 42 | }).ContinueInMainThread((result) => 43 | { 44 | DateTime dateTime = DateTime.FromBinary(result); 45 | Debug.Log("DateTime value: " + dateTime); 46 | }); 47 | } 48 | 49 | ### Execute a background task, enqueue the results into a threadsafe action queue to be printed out once the background task is done. The background task is repeated every second (1000 ms) 50 | 51 | private readonly Queue _actionQueue = new Queue(); 52 | public Queue ActionQueue 53 | { 54 | get 55 | { 56 | // Async class provide lock object with unique keyword identifier 57 | // for thread-safe operations 58 | lock (Async.GetLock("ActionQueue")) 59 | { 60 | return _actionQueue; 61 | } 62 | } 63 | } 64 | 65 | private void CalcAndReportRepeatedly() 66 | { 67 | Async.RunInBackground("CalcAndReportRepeatedly", 1000, () => 68 | { 69 | long date1 = DateTime.UtcNow.Ticks; 70 | Thread.Sleep(50); 71 | long date2 = DateTime.UtcNow.Ticks; 72 | ActionQueue.Enqueue(() => 73 | { 74 | Debug.Log("date1: " + date1 + " + date2: " + date2 + " = " + (date1 + date2)); 75 | }); 76 | }).ContinueInMainThread(() => 77 | { 78 | Action action = ActionQueue.Dequeue(); 79 | action(); 80 | }); 81 | } 82 | 83 | # Note 84 | Call Dispatcher.Instance.Reset() to abort and clear all scheduled background or threaded tasks if needed. For example, it's useful when your application restart. 85 | --------------------------------------------------------------------------------