Unity多線程管理
游戲中我們有許多地方還是有需求要開(kāi)啟多線程,例如下載文件,解壓文件等操作呛伴,我們需要在Unity下使用
多線程,那我們?nèi)绾文芨奖愕墓芾矶嗑€程呢谒所?
目前主要需要解決一下幾個(gè)問(wèn)題:
- 統(tǒng)一開(kāi)啟子線程热康,防止多線程濫用
- 子線程中如何回調(diào)主線程
我目前的解決方案
- 所有需要異步處理的任務(wù),都繼承
AsyncTask
劣领。 -
AsyncTask
封裝了執(zhí)行過(guò)程姐军,方便對(duì)任務(wù)的控制。 - 所有需要回調(diào)主線程的地方尖淘,統(tǒng)一添加
Action
奕锌。由主線程逐幀調(diào)用
代碼如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using LuaFramework;
/// <summary>
/// 異步任務(wù),交給子線程執(zhí)行
/// </summary>
public abstract class AsyncTask
{
// multiThreadMgr
protected MultiThreadManager MultiThreadMgr {
get {
return AppFacade.Instance.GetManager<MultiThreadManager> (ManagerName.MultiThread);
}
}
/// <summary>
/// 執(zhí)行任務(wù)
/// </summary>
public void Execute() {
try {
Run();
} finally {
MultiThreadMgr.FinishTask (this);
}
}
/// <summary>
/// 關(guān)閉執(zhí)行
/// </summary>
public abstract void Close ();
/// <summary>
/// 開(kāi)始運(yùn)行
/// </summary>
public abstract void Run ();
}
/// <summary>
/// 多線程管理器
/// </summary>
public class MultiThreadManager : Manager
{
// 需要在主線程執(zhí)行的操作
static List<Action> actions = new List<Action> ();
static List<Action> runningActions = new List<Action> ();
static object obj = new object();
// 異步任務(wù)隊(duì)列
static List<AsyncTask> taskList = new List<AsyncTask> ();
/// <summary>
/// 在主線程中執(zhí)行
/// </summary>
/// <param name="action">Action.</param>
public void RunOnMainThread (Action action)
{
lock (obj) {
actions.Add (action);
}
}
/// <summary>
/// 添加異步任務(wù)
/// </summary>
/// <param name="runnable">Runnable.</param>
public void AddAsyncTask (AsyncTask runnable)
{
Debug.Log("AddTask:" + runnable.ToString());
taskList.Add (runnable);
Thread thread = new Thread (runnable.Execute);
thread.IsBackground = true;
thread.Start ();
}
/// <summary>
/// 完成異步任務(wù)
/// </summary>
/// <param name="runnable">Runnable.</param>
public void FinishTask (AsyncTask runnable)
{
taskList.Remove (runnable);
Debug.Log ("RemoveTask:" + runnable.ToString () + "," + taskList.Count);
}
/// <summary>
/// 主線程更新
/// </summary>
void Update ()
{
lock (obj) {
runningActions.Clear ();
runningActions.AddRange (actions);
actions.Clear ();
}
// 處理主線程事件
if (runningActions.Count > 0) {
foreach(Action action in runningActions) {
action ();
}
}
runningActions.Clear ();
}
void OnDestroy() {
for (int i = 0; i < taskList.Count; i++) {
taskList [i].Close ();
}
}
}