Unity多线程管理
2016-12-12 本文已影响649人
Aodota
Unity多线程管理
游戏中我们有许多地方还是有需求要开启多线程,例如下载文件,解压文件等操作,我们需要在Unity下使用
多线程,那我们如何能更方便的管理多线程呢?
目前主要需要解决一下几个问题:
- 统一开启子线程,防止多线程滥用
- 子线程中如何回调主线程
我目前的解决方案
- 所有需要异步处理的任务,都继承
AsyncTask
。 -
AsyncTask
封装了执行过程,方便对任务的控制。 - 所有需要回调主线程的地方,统一添加
Action
。由主线程逐帧调用
代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using LuaFramework;
/// <summary>
/// 异步任务,交给子线程执行
/// </summary>
public abstract class AsyncTask
{
// multiThreadMgr
protected MultiThreadManager MultiThreadMgr {
get {
return AppFacade.Instance.GetManager<MultiThreadManager> (ManagerName.MultiThread);
}
}
/// <summary>
/// 执行任务
/// </summary>
public void Execute() {
try {
Run();
} finally {
MultiThreadMgr.FinishTask (this);
}
}
/// <summary>
/// 关闭执行
/// </summary>
public abstract void Close ();
/// <summary>
/// 开始运行
/// </summary>
public abstract void Run ();
}
/// <summary>
/// 多线程管理器
/// </summary>
public class MultiThreadManager : Manager
{
// 需要在主线程执行的操作
static List<Action> actions = new List<Action> ();
static List<Action> runningActions = new List<Action> ();
static object obj = new object();
// 异步任务队列
static List<AsyncTask> taskList = new List<AsyncTask> ();
/// <summary>
/// 在主线程中执行
/// </summary>
/// <param name="action">Action.</param>
public void RunOnMainThread (Action action)
{
lock (obj) {
actions.Add (action);
}
}
/// <summary>
/// 添加异步任务
/// </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>
/// 完成异步任务
/// </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 ();
}
}
}