C# 多线程实践
以下工具会把一个总任务拆分成多个子任务,交给多个线程同时执行。使用时只需要传入线程数,总任务列表和执行方法即可。
MultiThreadProcessor
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleTest
{
public class MultiThreadProcessor<T>
{
public MultiThreadProcessor(int _threadCount, Action<List<T>> _action)
{
threadCount = _threadCount;
waitingThreadCount = _threadCount;
action = _action;
}
private int threadCount;
private int waitingThreadCount;
private AutoResetEvent autoEvent;
private Action<List<T>> action;
public void MultiTaskExecute(List<T> taskList)
{
autoEvent = new AutoResetEvent(false);
int totalCount = taskList.Count;
int lastProcessCount = totalCount % (threadCount - 1);
int perThreadProcessCount = (totalCount - lastProcessCount) / (threadCount - 1);
int takeIndex = 0;
int threadTakeCount = perThreadProcessCount;
for (int threadIndex = 1; threadIndex <= threadCount; threadIndex++)
{
List<T> executeList = new List<T>();
if (threadIndex == threadCount)
{
threadTakeCount = lastProcessCount;
}
int endIndex = takeIndex + threadTakeCount;
for (; takeIndex < endIndex; takeIndex++)
{
executeList.Add(taskList[takeIndex]);
}
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), executeList);
}
autoEvent.WaitOne();
}
private void DoTask(object obj)
{
List<T> list = obj as List<T>;
if (list != null && list.Count > 0)
{
action.Invoke(list);
}
if (Interlocked.Decrement(ref waitingThreadCount) == 0)
{
autoEvent.Set();
}
}
}
}
使用示例
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleTest
{
class Program
{
List<int> totalTasks = new List<int>();
for (int i = 0; i< 37; i++)
{
totalTasks.Add(i);
}
MultiThreadProcessor<int> threadTool = new MultiThreadProcessor<int>(10, ExecuteTask);
threadTool.MultiTaskExecute(totalTasks);
Console.WriteLine("Process End!");
Console.ReadLine();
}
private static void ExecuteTask(List<int> list)
{
Random rd = new Random();
Thread.Sleep(rd.Next(1, 1000));
Console.WriteLine($"{string.Join(',', list)}, Count: {list.Count}");
}
}
测试结果

网友评论