.NET使用Task动态创建多任务多线程并行程序计算Redis集群keys计算
2017-11-22 14:23
826 查看
Task是一个很好用的多任务处理类,并且通过Task可以对任务进行很好的控制。
下面将通过代码实现Redis集群在使用IServer.keys时通过多任务对多个服务器示例进行并行计算,并对返回key做汇总计算。
对于主从双服务器的redis使用keys可以很方便的取到所提供的正则匹配KEY集合,但在redis集群中每次只能获取一个redis实例匹配keys,如果先去遍历所有服务器则会十分慢,并且容易出现超时计算,这时我们就用Task为每台Reids服务器做一个异步的Task等待最后一个处理完汇总数据,这样可以大大提升效率。
当然应用在其他地方也是可以的用在任何大批量处理的程序中,掌握Task的使用可谓是一劳永逸。
定义一个异步方法读取redis节点的key
封装新的keys查询方法
这里主要用到Parallel.ForEach,可以动态创建多个Task,也可以使用Parallel.For。重点:切记这里不能用单纯的for 或者foreach去循环创建Task,即使可以创建,会发现在异步取数据时从第二次年开始每个任务所执行的内容都是相同的。
下面将通过代码实现Redis集群在使用IServer.keys时通过多任务对多个服务器示例进行并行计算,并对返回key做汇总计算。
对于主从双服务器的redis使用keys可以很方便的取到所提供的正则匹配KEY集合,但在redis集群中每次只能获取一个redis实例匹配keys,如果先去遍历所有服务器则会十分慢,并且容易出现超时计算,这时我们就用Task为每台Reids服务器做一个异步的Task等待最后一个处理完汇总数据,这样可以大大提升效率。
当然应用在其他地方也是可以的用在任何大批量处理的程序中,掌握Task的使用可谓是一劳永逸。
定义一个异步方法读取redis节点的key
/// <summary> /// 异步任务获取单个Redis匹配keys /// </summary> /// <param name="endpoint">redis节点</param> /// <param name="pattern">匹配的key例如:key:*</param> /// <returns></returns> public async Task<RedisKey[]> GetdkeysbyServer(EndPoint endpoint, string pattern) { var server = RdsCon.GetServer(endpoint); if (server.IsConnected)//判断节点是否可以连接 { if (server.IsSlave)//判断是否为主库,因为存在很多从库,主库断掉后从库会充当主库,所以这里只检查主库数据 { return null; } } else { return null; } var keys = server.Keys(database: Database.Database, pattern: pattern).ToArray(); return keys; }
封装新的keys查询方法
这里主要用到Parallel.ForEach,可以动态创建多个Task,也可以使用Parallel.For。重点:切记这里不能用单纯的for 或者foreach去循环创建Task,即使可以创建,会发现在异步取数据时从第二次年开始每个任务所执行的内容都是相同的。
/// <summary> /// 查找所有符合给定模式 pattern 的 key;KEYS * 匹配数据库中所有 key;KEYS h?llo 匹配 hello,hallo等。KEYS h[ae]llo匹配hello和hallo /// </summary> /// <param name="pattern"></param> /// <returns></returns> public string[] Keys(string pattern) { List<RedisKey> listkey = new List<RedisKey>(); List<Task<RedisKey[]>> arrayTask = new List<Task<RedisKey[]>>(); Parallel.ForEach(RdsCon.GetEndPoints(), item => { Task<RedisKey[]> newtask = GetdkeysbyServer(item, pattern); if (newtask != null) { arrayTask.Add(newtask); } }); Task.WaitAll(arrayTask.ToArray()); foreach (var taskitem in arrayTask) { if (taskitem.Result != null) { listkey.AddRange(taskitem.Result); } } return listkey.Select(e => (string)e).ToArray<string>(); }
相关文章推荐
- 并行模式库PPL应用实战(一):使用task类创建并行任务
- 在.NET客户端程序中使用多线程(二)
- ABAP--动态创建类型和变量的使用程序样例
- ABAP--动态创建类型和变量的使用程序样例
- 浅谈.NET下的多线程和并行计算(六)线程池基础下
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- 浅谈.NET下的多线程和并行计算(六)线程池基础下 (转)
- 浅谈.NET下的多线程和并行计算(一)前言
- 浅谈.NET下的多线程和并行计算(二)线程基本知识
- .NET中一般处理程序(ashx)在Ajax中的使用--下拉列表的动态级连
- 在.net中使用Udp协议创建简单的聊天程序
- 浅谈.NET下的多线程和并行计算(九)Winform中多线程编程基础下
- 浅谈.NET下的多线程和并行计算(八)Winform中多线程编程基础上
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- ABAP--动态创建类型和变量的使用程序样例
- 浅谈.NET下的多线程和并行计算(十一).NET异步编程模型基础下
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- 浅谈.NET下的多线程和并行计算(五)线程池基础上 (转)
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图