自上篇介绍完ThreadManager类后,多线程异步任务工具基本完成。本篇介绍使用该工具,ThreadingTest.cs:线程使用测试类,供参考使用。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using System;
using UnityEngine.UI;
/*
* Author:W
* 线程应用测试
* 1.主线程应用测试
* 2.独立线程[Thread]应用测试
* 3.多任务异步【主线程的协程Coroutine 或 线程池ThreadPool】处理应用测试
*/
namespace W.GameFramework.MultiThread
{
/// <summary>
/// 像素
/// </summary>
public struct Pixel
{
public int x;
public int y;
public Pixel(int x, int y)
{
this.x = x;
this.y = y;
}
}
public class ThreadingTest : MonoBehaviour
{
/// <summary>
/// 单线程处理不带参数的任务
/// </summary>
Thread threadA;
/// <summary>
/// 单线程处理带参数的任务
/// </summary>
Thread threadB;
/// <summary>
/// 处理多任务的线程池对象
/// </summary>
ThreadPoolHelper threadPoolHelper;
/// <summary>
/// 设置此次任务执行需要的最大线程数
/// 值越大,分的批次越多
/// </summary>
private int MaxThreads = 3;
/// <summary>
/// 是有强制使用主线程的协程来处理任务
/// </summary>
private bool ForceToMainThread = false;
/// <summary>
/// 显示贴图
/// </summary>
public RawImage RawImage;
/// <summary>
/// 待处理的2D贴图
/// </summary>
public Texture2D Texture;
/// <summary>
/// 模糊的范围值
/// </summary>
private int BlurRange = 3;
/// <summary>
/// 像素源
/// </summary>
private Pixel[] SourcePixels;
/// <summary>
/// 获取一张贴图的所有像素色值
/// </summary>
private Color32[] OrigionalColors;
/// <summary>
/// 获取目标像素色值
/// </summary>
private Color32[] DestinationColors;
/// <summary>
///
/// </summary>
private Color32[] SourceColors;
/// <summary>
/// 贴图宽度
/// </summary>
private int TextureWidth;
/// <summary>
/// 贴图高度
/// </summary>
private int TextureHeight;
/// <summary>
/// 显示纹理
/// </summary>
private Texture2D DisplayTexture;
void Awake()
{
ThreadManager.Instance.Init();
DisplayTexture = new Texture2D(Texture.width, Texture.height, TextureFormat.ARGB32, false);
TextureWidth = Texture.width;
TextureHeight = Texture.height;
RawImage.texture = DisplayTexture;
OrigionalColors = Texture.GetPixels32();
SourcePixels = new Pixel[OrigionalColors.Length];
DestinationColors = new Color32[OrigionalColors.Length];
SourceColors = new Color32[OrigionalColors.Length];
int i = 0;
for (int y = 0; y < Texture.height; y++)
{
for (int x = 0; x < Texture.width; x++)
{
SourcePixels[i] = new Pixel(x, y);
i++;
}
}
}
// Use this for initialization
void Start()
{
threadA = ThreadManager.Instance.DealTaskBySingleThread(ThreadAStart,System.Threading.ThreadPriority.Normal);
threadB = ThreadManager.Instance.DealTaskBySingleThread(ThreadBParamStart,"Hello World!",System.Threading.ThreadPriority.Normal);
threadPoolHelper = ThreadManager.Instance.CreateThreadPoolHelper();
StartBluringTexture();
}
/// <summary>
/// 开始模糊贴图
/// </summary>
private void StartBluringTexture()
{
StartCoroutine(BlurTextureSampled());
}
private IEnumerator BlurTextureSampled()
{
yield return new WaitForEndOfFrame();
Array.Copy(OrigionalColors, SourceColors, OrigionalColors.Length);
//开启线程池计算处理贴图的模糊
ThreadManager.Instance.DealMultiThreadedTaskExecution(BlurPixels, SourcePixels, OnComplete, OnTaskDataComplete, MaxThreads, threadPoolHelper, ForceToMainThread);
//循环检查多任务线程是否执行完成
while (threadPoolHelper.IsBusy)
yield return new WaitForSeconds(0.001f);
//贴图模糊数据计算完毕后,设置贴图
DisplayTexture.SetPixels32(DestinationColors);
DisplayTexture.Apply();
}
/// <summary>
/// 像素模糊处理
/// </summary>
/// <param name="pixel"></param>
/// <param name="i"></param>
public void BlurPixels(Pixel pixel, int i)
{
int r = 0;
int g = 0;
int b = 0;
int range = Math.Max(1, BlurRange);
int xMin = Mathf.Max(0, pixel.x - range);
int yMin = Mathf.Max(0, pixel.y - range);
int xMax = Mathf.Min(TextureWidth, pixel.x + range);
int yMax = Mathf.Min(TextureHeight, pixel.y + range);
int total = 0;
for (int y = yMin; y < yMax; y++)
{
int yRow = y * TextureWidth;
for (int x = xMin; x < xMax; x++)
{
Color32 color = SourceColors[x + yRow];
r += color.r;
g += color.g;
b += color.b;
total++;
}
}
DestinationColors[i] = new Color32((byte)(r / total), (byte)(g / total), (byte)(b / total), (byte)255);
}
/// <summary>
/// 所有像素处理的回调
/// </summary>
/// <param name="tasks"></param>
private void OnComplete(Pixel[] tasks)
{
Debug.Log("所有的像素处理完毕 : " + tasks.Length);
}
/// <summary>
/// 该批次的像素像素处理完成的回调
/// </summary>
/// <param name="taskPartial"></param>
/// <param name="firstIndex"></param>
/// <param name="lastIndex"></param>
private void OnTaskDataComplete(Pixel[] taskPartial, int firstIndex, int lastIndex)
{
Debug.Log("该批次的像素任务处理完毕: " + taskPartial.Length + ", from: " + firstIndex + ", to: "+ lastIndex);
}
/// <summary>
/// 单线程A处理的任务函数
/// </summary>
private void ThreadAStart()
{
Debug.Log("Thread A 开始执行任务");
ThreadManager.Instance.WaitForNextFrame(30);
ThreadManager.Instance.DealTaskByMainThread(()=> { Debug.Log("Thread A 等待了30帧执行,当前帧数为: " + Time.frameCount); });
ThreadManager.Instance.WaitForSeconds(10);
ThreadManager.Instance.DealTaskByMainThread(()=> { Debug.Log("Thread A 又等待了10秒执行,当前帧数为: " + Time.frameCount); });
}
/// <summary>
/// 单线程B处理的带参数任务函数
/// </summary>
/// <param name="param"></param>
private void ThreadBParamStart(object param)
{
Debug.Log("Thread B 开始执行任务");
ThreadManager.Instance.WaitForNextFrame(50);
Debug.Log("Thread B 输出传入参数param = "+param.ToString());
}
// Update is called once per frame
void Update()
{
}
}
}
运行结果如下:
最后附上插件工具链接:https://pan.baidu.com/s/1onZ5qYXoXzQqyzKiQvP4GQ 提取码:ossj