# Others

### Lập trình bất đồng bộ

Lập trình bất đồng bộ là kỹ thuật lập trình cho phép dừng tiến trình mà không chặn luồng chính.

- ****async****<span style="white-space: pre-wrap;"> là từ khóa dùng để khai báo phương thức bất đồng bộ. Phương thức bất đồng bộ có thể trả về giá trị hoặc không.</span>
- ****await**** cho phép nhường quyền điều khiển và tiếp tục thực thi khi tác vụ hoàn tất.

****Tác dụng:****

- Giữ UI/Gameplay mượt khi chờ I/O (HTTP, file, DB).
- <span style="white-space: pre-wrap;">Dễ chạy </span>****đồng thời****<span style="white-space: pre-wrap;"> nhiều I/O với </span>`<span class="editor-theme-code">Task.WhenAll(...)</span>`.
- <span style="white-space: pre-wrap;">Đẩy việc </span>****CPU-bound****<span style="white-space: pre-wrap;"> ra nền bằng </span>`<span class="editor-theme-code">Task.Run(...)</span>`.

****Ưu điểm:****

- Code tuyến tính, dễ đọc.
- Không block thread → scalable.
- Hỗ trợ hủy (`<span class="editor-theme-code">CancellationToken</span>`) và gom lỗi chuẩn.

****Nhược điểm / Lỗi hay gặp:****

- `<span class="editor-theme-code">.Result</span>`/`<span class="editor-theme-code">.Wait()</span>`<span style="white-space: pre-wrap;"> trên main/UI → deadlock.</span>
- `<span class="editor-theme-code">async void</span>`<span style="white-space: pre-wrap;"> (trừ event) khó bắt lỗi.</span>
- <span style="white-space: pre-wrap;">Đồng bộ hoá context phức tạp (cẩn trọng </span>`<span class="editor-theme-code">ConfigureAwait(false)</span>`<span style="white-space: pre-wrap;"> trong lib).</span>

### UniTask

<span style="white-space: pre-wrap;">UniTask là thư viện async tối ưu GC cho Unity. Cung cấp awaiter cho </span>`<span class="editor-theme-code">AsyncOperation</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">UnityWebRequest</span>`, Addressables… và tích hợp PlayerLoop.

****Tác dụng:****

- `<span class="editor-theme-code">await</span>`<span style="white-space: pre-wrap;"> trực tiếp Unity API (load scene, asset, web request).</span>
- <span style="white-space: pre-wrap;">Giảm cấp phát so với </span>`<span class="editor-theme-code">Task</span>`.
- Điều khiển thời điểm tiếp tục (Update/LateUpdate/FixedUpdate).
- <span style="white-space: pre-wrap;">Hủy theo vòng đời object: </span>`<span class="editor-theme-code">GetCancellationTokenOnDestroy()</span>`.

****Ưu điểm:****

- Hiệu năng/GC tốt, sát Unity main thread.
- <span style="white-space: pre-wrap;">API phong phú: </span>`<span class="editor-theme-code">UniTask.WhenAll</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Delay</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Yield</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">.Forget(handler)</span>`.

****Nhược điểm / Lưu ý:****

- Thêm phụ thuộc vào bên thứ ba.
- Cần quản lý PlayerLoop &amp; hủy đúng cách để tránh leak.
- <span style="white-space: pre-wrap;">Fire-and-forget phải </span>****log/bắt lỗi****<span style="white-space: pre-wrap;"> (</span>`<span class="editor-theme-code">.Forget(ex => LogException)</span>`).

****Gợi ý nhanh:****

- <span style="white-space: pre-wrap;">I/O: tạo nhiều tác vụ → </span>`<span class="editor-theme-code">WhenAll</span>`.
- <span style="white-space: pre-wrap;">CPU: </span>`<span class="editor-theme-code">Task.Run</span>`.
- <span style="white-space: pre-wrap;">Tránh </span>`<span class="editor-theme-code">.Result</span>`/`<span class="editor-theme-code">.Wait()</span>`<span style="white-space: pre-wrap;">; tránh </span>`<span class="editor-theme-code">async void</span>`.
- <span style="white-space: pre-wrap;">Unity: ưu tiên </span>****UniTask****<span style="white-space: pre-wrap;">, luôn dùng </span>`<span class="editor-theme-code">CancellationToken</span>`<span style="white-space: pre-wrap;"> gắn vòng đời object.</span>

### Garbage Collection (GC)

****GC****<span style="white-space: pre-wrap;"> là bộ thu gom rác tự động của .NET quản lý </span>****vòng đời đối tượng****<span style="white-space: pre-wrap;"> trên </span>****managed heap. GC**** <span style="white-space: pre-wrap;">tự phát hiện đối tượng </span>****không còn tham chiếu****<span style="white-space: pre-wrap;">, thu hồi bộ nhớ, và (thường) </span>****nén****<span style="white-space: pre-wrap;"> vùng heap để giảm phân mảnh.</span>

#### Cách hoạt động

- ****Phân tầng****<span style="white-space: pre-wrap;">: </span>
    - Gen0: ngắn hạn, được dọn dẹp thường xuyên và rất nhanh
    - Gen1, Gen2: trung hạn và dài hạn, dữ liệu không bị dọn dẹp ở Gen0 sẽ được chuyển lên Gen1 và Gen2. Những tầng này ít bị dọn dẹp hơn. Khi dọn dẹp sẽ tốn thời gian hơn.
- ****LOH (Large Object Heap)****<span style="white-space: pre-wrap;">: </span>
    - <span style="white-space: pre-wrap;">Dữ liệu ≥ ~85KB cấp phát ở LOH; </span>
    - <span style="white-space: pre-wrap;">Dữ liệu này thường </span>****không nén****<span style="white-space: pre-wrap;"> mỗi lần GC. Được sắp xếp lại mỗi lần dọn dẹp.</span>
    - Có thể gây phân mảnh
- ****Tạm dừng (STW)****: Để đảm bảo dọn dẹp hiệu quả GC sẽ yêu cầu chương trình tạm dừng để dọn dẹp.
- ****Thời điểm kích hoạt****<span style="white-space: pre-wrap;">: </span>
    - Khi thiếu bộ nhớ để cấp phát, áp lực bộ nhớ cao.
    - <span style="white-space: pre-wrap;">Khi gọi </span>`<span class="editor-theme-code">GC.Collect()</span>`<span style="white-space: pre-wrap;"> (không khuyến khích).</span>

#### <span style="white-space: pre-wrap;">Destructor &amp; </span>`<span class="editor-theme-code">IDisposable</span>`

- ****destructor**** (`<span class="editor-theme-code">~Type()</span>`<span style="white-space: pre-wrap;">): chạy </span>****không xác định thời điểm****<span style="white-space: pre-wrap;"> trên thread GC; chỉ dùng khi giữ </span>****tài nguyên unmanaged****.
- **`<strong class="editor-theme-bold editor-theme-code">IDisposable</strong>`**/**`<strong class="editor-theme-bold editor-theme-code">using</strong>`**<span style="white-space: pre-wrap;">: giải phóng tài nguyên </span>****đúng lúc****<span style="white-space: pre-wrap;"> (socket, file, handle…). Với unmanaged, dùng pattern </span>`<span class="editor-theme-code">Dispose</span>`<span style="white-space: pre-wrap;"> + </span>`<span class="editor-theme-code">SafeHandle</span>`.
- <span style="white-space: pre-wrap;">Quy tắc: </span>****Ưu tiên** `<strong class="editor-theme-bold editor-theme-code">Dispose</strong>`**; chỉ dùng destructor như “lưới an toàn”.

#### Những hiểu lầm thường gặp

- <span style="white-space: pre-wrap;">“Dùng </span>`<span class="editor-theme-code">GC.Collect()</span>`<span style="white-space: pre-wrap;"> là tối ưu” → </span>****Sai****<span style="white-space: pre-wrap;">: thường làm </span>****tệ hơn****<span style="white-space: pre-wrap;"> vì tăng STW.</span>
- <span style="white-space: pre-wrap;">“Dùng List/Dictionary để tránh phân mảnh” → </span>****Không chính xác****<span style="white-space: pre-wrap;">: GC mới xử lý phân mảnh; vấn đề lớn ở </span>****LOH****<span style="white-space: pre-wrap;"> và </span>****pinning****.
- <span style="white-space: pre-wrap;">“GC luôn chậm” → </span>****Phụ thuộc mẫu cấp phát****<span style="white-space: pre-wrap;">; tối ưu </span>****mẫu cấp phát****<span style="white-space: pre-wrap;"> thường hiệu quả hơn “tắt/bắt” GC.</span>

#### Best practices

- ****Giảm cấp phát****<span style="white-space: pre-wrap;">: tái sử dụng buffer; dùng </span>`<span class="editor-theme-code">ArrayPool<T></span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">StringBuilder</span>`, cache hợp lý.
- ****Tránh boxing****<span style="white-space: pre-wrap;"> (struct → object), tránh LINQ tạo rác trong hot path.</span>
- ****Chú ý vòng đời tham chiếu****<span style="white-space: pre-wrap;">: đừng giữ tham chiếu lâu “vô tình” (static cache, event không hủy đăng ký) → đối tượng lên </span>****Gen2****.
- ****LOH****<span style="white-space: pre-wrap;">: hạn chế tạo nhiều mảng lớn; chia nhỏ/thuê từ </span>`<span class="editor-theme-code">ArrayPool<T></span>`.
- ****Pinning****<span style="white-space: pre-wrap;"> (</span>`<span class="editor-theme-code">fixed</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">GCHandleType.Pinned</span>`): dùng ít – pin lâu gây phân mảnh.
- ****API hiện đại****<span style="white-space: pre-wrap;">: </span>`<span class="editor-theme-code">Span<T></span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Memory<T></span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">ReadOnlySpan<T></span>`<span style="white-space: pre-wrap;"> cho xử lý dữ liệu không cấp phát.</span>
- ****Thiết lập GC****:
    - ****Server GC****<span style="white-space: pre-wrap;"> (dịch vụ/đa nhân nặng) vs </span>****Workstation GC****<span style="white-space: pre-wrap;"> (ứng dụng desktop).</span>
    - `<span class="editor-theme-code">GCLatencyMode.LowLatency</span>`/`<span class="editor-theme-code">TryStartNoGCRegion</span>`<span style="white-space: pre-wrap;"> chỉ dùng ngắn hạn, có kiểm soát.</span>

#### Với Unity

- ****Incremental GC****<span style="white-space: pre-wrap;"> (Unity 2019.3+): giảm thời gian dừng bằng cách chia nhỏ công việc GC. Bật trong </span>****Project Settings &gt; Player &gt; Garbage Collector****.
- ****Tránh cấp phát mỗi frame****:
    - Không tạo string/`<span class="editor-theme-code">new</span>`<span style="white-space: pre-wrap;"> trong </span>`<span class="editor-theme-code">Update()</span>`<span style="white-space: pre-wrap;">; tránh LINQ/closure/boxing trong </span>`<span class="editor-theme-code">Update()</span>`.
    - <span style="white-space: pre-wrap;">Dùng </span>****object pooling****<span style="white-space: pre-wrap;"> cho bullets, VFX, particle, v.v.</span>
    - <span style="white-space: pre-wrap;">Ưu tiên </span>****struct****/Burst/DOTS cho luồng hiệu năng cao.
- ****Profiler****<span style="white-space: pre-wrap;">: theo dõi </span>`<span class="editor-theme-code">GC.Alloc</span>`<span style="white-space: pre-wrap;"> và spikes; kiểm tra callsite gây rác.</span>
- ****Addressables/Assets****: giải phóng đúng cách (`<span class="editor-theme-code">Release</span>`/`<span class="editor-theme-code">UnloadUnusedAssets</span>`) để giảm áp lực heap.

#### Checklist tối ưu GC

- <span style="white-space: pre-wrap;"> Không gọi </span>`<span class="editor-theme-code">GC.Collect()</span>`<span style="white-space: pre-wrap;"> trừ khi thật cần.</span>
- <span style="white-space: pre-wrap;"> Dọn </span>****event handlers****<span style="white-space: pre-wrap;"> (unsubscribe) để tránh giữ tham chiếu lâu.</span>
- <span style="white-space: pre-wrap;"> Dùng </span>`<span class="editor-theme-code">using</span>`/`<span class="editor-theme-code">Dispose()</span>`<span style="white-space: pre-wrap;"> cho tài nguyên ngoài managed.</span>
- <span style="white-space: pre-wrap;"> Pool hóa bộ nhớ &amp; đối tượng “ngắn hạn nóng”.</span>
- <span style="white-space: pre-wrap;"> Tránh cấp phát trong </span>`<span class="editor-theme-code">Update()</span>`<span style="white-space: pre-wrap;">/hot path; kiểm tra bằng </span>****Profiler****.
- <span style="white-space: pre-wrap;"> Cẩn trọng với </span>****LOH****<span style="white-space: pre-wrap;"> &amp; </span>****pinning****<span style="white-space: pre-wrap;">; ưu tiên chia nhỏ hoặc </span>`<span class="editor-theme-code">ArrayPool<T></span>`.
- <span style="white-space: pre-wrap;"> Với Unity: bật </span>****Incremental GC****<span style="white-space: pre-wrap;"> khi phù hợp, tránh tạo rác frame-by-frame.</span>

<p class="callout danger">**Tối ưu GC = tối ưu* ****mẫu cấp phát**** *+ quản* ****vòng đời tham chiếu*****, không phải “gọi GC nhiều hơn”.</p>