最近遇到了一个业务场景,需要对List中的数据逐个发起http请求(List中的数据各自独立,对执行顺序无要求),考虑到可以使用多线程加快处理速度。
封装了如下方法:
/// <summary>
/// 多线程处理数据-无返回值
/// </summary>
/// <param name="list"></param>
/// <param name="action">数据处理方法</param>
/// <param name="threadCount">开启线程数量</param>
/// <param name="waitFlag">是否等待全部结束</param>
static void RunTask<T>(List<T> list, Action<T> action, int threadCount = 5, bool waitFlag = true)
{
var queue = new ConcurrentQueue<T>(list);
threadCount = Math.Min(threadCount, list.Count);
Task[] tasks = new Task[threadCount];
for (int i = 0; i < threadCount; i++)
{
tasks[i] = Task.Run(() =>
{
while (queue.TryDequeue(out T t))
{
action(t);
}
});
}
if (waitFlag)
{
Task.WaitAll(tasks);
}
}
/// <summary>
/// 多线程处理数据-有返回值
/// </summary>
/// <param name="list">待处理数据</param>
/// <param name="func">数据处理方法</param>
/// <param name="count">开启线程数量</param>
static List<TReturn> RunTask<T, TReturn>(List<T> list, Func<T, TReturn> func, int threadCount = 5)
{
var result = new ConcurrentBag<TReturn>();
var queue = new ConcurrentQueue<T>(list);
threadCount = Math.Min(threadCount, list.Count);
var tasks = new Task[threadCount];
for (int i = 0; i < threadCount; i++)
{
tasks[i] = Task.Run(() =>
{
while (queue.TryDequeue(out T t))
{
result.Add(func(t));
}
});
}
Task.WaitAll(tasks);
return result.ToList();
}
使用示例:
public void DoSingle(User user, string param1, string param2)
{
//HttpHelper.Get("http://xxxx/userid="+user.id);
//doSomething();
Console.WriteLine(user.Id + "-" + user.Name + "-" + param1 + "-" + param2);
}
public string DoSingle2(User user, string param1, string param2)
{
//HttpHelper.Get("http://xxxx/userid="+user.id);
//doSomething();
Console.WriteLine(user.Id + "-" + user.Name + "-" + param1 + "-" + param2);
return user.Id + "-666";
}
public class User
{
/// <summary>
/// id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
}
public void Test()
{
var list = new List<User> {
new User { Id = 1, Name = "张三" },
new User { Id = 2, Name = "李四" },
new User { Id = 3, Name = "王五" }
};
RunTask(list, t => DoSingle(t, "参数1", "参数2"));
var retList = RunTask(list, t => DoSingle2(t, "参数1", "参数2"));
}
更多【list-使用多线程处理List数据】相关视频教程:www.yxfzedu.com