###### tags: `None` <style> html, body, .ui-content { background-color: #333; color: #ddd; } body > .ui-infobar { display: none; } .ui-view-area > .ui-infobar { display: block; } .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { color: #ddd; } .markdown-body h1, .markdown-body h2 { border-bottom-color: #ffffff69; } .markdown-body h1 .octicon-link, .markdown-body h2 .octicon-link, .markdown-body h3 .octicon-link, .markdown-body h4 .octicon-link, .markdown-body h5 .octicon-link, .markdown-body h6 .octicon-link { color: #fff; } .markdown-body img { background-color: transparent; } .ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a { color: white; border-left: 2px solid white; } .expand-toggle:hover, .expand-toggle:focus, .back-to-top:hover, .back-to-top:focus, .go-to-bottom:hover, .go-to-bottom:focus { color: white; } .ui-toc-dropdown { background-color: #333; } .ui-toc-label.btn { background-color: #191919; color: white; } .ui-toc-dropdown .nav>li>a:focus, .ui-toc-dropdown .nav>li>a:hover { color: white; border-left: 1px solid white; } .markdown-body blockquote { color: #bcbcbc; } .markdown-body table tr { background-color: #5f5f5f; } .markdown-body table tr:nth-child(2n) { background-color: #4f4f4f; } .markdown-body code, .markdown-body tt { color: #eee; background-color: rgba(230, 230, 230, 0.36); } a, .open-files-container li.selected a { color: #5EB7E0; } </style> 關於UniTask的使用規範 - 起因 : @samshiao 提出的一些想法 - 是否應該通過規範減少 async void 函式的使用 - 承上, 是否應要求 async void改為寫 async UniTaskVoid - 承上, 是否應要求 async 函式應至少返回UniTask, 或UniTask<T> - 承上, 討論時發現, 當上述要求成立時, 會與我們目前Async結尾的規範combo, 從而產生更多Async結尾function --- 目前看法 : @samshiao 的要求是有道理的 --- 先做簡單總結, 大家看看實行上, 是否有難處, 後面再談細節 - 不特地朔及既往改code, 路過時一個個慢慢改進 - `async void` 寫法 只用於不得已的情形, Ex : 合作對象為System.Action - `async UniTaskVoid` 寫法作為 `async void` 替代品 - 但仍應只用於有必要的地方, 即 : 你確定此function, 不可能有任何需要加入任何Task鍊的情況 - `async UniTask` & `async UniTask<T>` 作為大多數非同步function的預設建議寫法 - 相望得到的好處是 - 能順利建立Task鍊, 便於統一處理錯誤 - 各函式間的合作能更順利, 因為你能隨時通過await等對方結束, 也能隨時選擇Forget不等他, 不再需要大幅度改code - 預設錯誤處理方式, 建議為throw new XXXXXException(); - 允許需要的人自行try catch - 是否繼續向上 `throw;` 應被討論 - 承上, 因大多數async function 都建議預設回Task, 故會連鎖引發目前的一個Async結尾命名規範 - 想跟大家討論看看, 繼續寫Async結尾的必要性, Async結尾的function感覺會有點多 --- 補充 - Task鍊 ``` 當所有function都通過返回Task或UniTask方式運行後 這些連鎖的function call調用, 即形成Task鍊 過程中有任何一人發生錯誤 終端都能夠通過try catch得知 例如: try { await A().B().C().D(); } catch(Exception e) { Debug.LogError(e); } 上例中 ABCD任何一個throw error, 終端的try catch都能接到 所以程式能輕易提供, 統一且低耦合的ErrorHandle機制 ``` - `async void` 在巨硬的建議中, 只應用於必要的地方(不得不這樣寫的地方) - `async void` 這樣寫能優於 `await UniTaskVoid` 的地方是, IDE不會提醒你要 `XxxxAsync().Forget();` - 背後付出轉型代價, 根據巨硬文件得知 - `async UniTaskVoid` 寫法 - `好處` 得到的好處是不用付轉型開銷, 因回傳的是readonly struct - `好處` 可透過 `UniTaskScheduler.UnobservedTaskExcetion` 事件, 統一攔截到被打斷的Task chain所產生的Excetion訊息 - `代價` 要支付.Forget() function call(空的function call), 以消除IDE的warning --- 參考文件 - [巨硬MSDN Best Practices in Asynchronous Programming](https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming) - [UniTask 的 UniTaskVoid.cs](https://github.com/Cysharp/UniTask/blob/18f2746f0d30a1b870d9835f2f16d15b56476a33/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskVoid.cs)