Unity-线程工具(六)

自上篇介绍完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

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Data菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值