C# 多线程双色球项目
1 2 3 4 5 6 7 | /// 多线程双色球项目-- /// 1 理解需求: /// 双色球:投注号码由6个红色球号码和1个蓝色球号码组成。 /// 红色球号码从01--33中选择,不重复 /// 蓝色球号码从01--16中选择 /// /// 球号码随机的规则,远程获取一个随机数据的,这个会有较长的时间损耗 |
前置数据准备
public frmSSQ() { InitializeComponent(); this.btnStart.Enabled = true; this.btnStop.Enabled = false; } #region Data /// <summary> /// 红球集合 其实可以写入配置文件 /// </summary> private string[] RedNums = { "01","02","03","04","05","06","07","08","09","10", "11","12","13","14","15","16","17","18","19","20", "21","22","23","24","25","26","27","28","29","30", "31","32","33" }; /// <summary> /// 蓝球集合 /// </summary> private string[] BlueNums = { "01","02","03","04","05","06","07","08","09","10", "11","12","13","14","15","16" }; private bool IsGoOn = true; private List<Task> taskList = new List<Task>(); #endregion
/// <summary> /// new Random().Next(1, 100); 多线程同时执行结果很高概率相同, /// 是用的当前时间为seed,时间相同结果相同 /// /// 解决随机数重复问题 /// 同时模拟远程请求的随机延时 /// </summary> public class RandomHelper { /// <summary> /// 随机获取数字并等待1~2s /// </summary> /// <returns></returns> public int GetRandomNumberDelay(int min, int max) { Thread.Sleep(this.GetRandomNumber(500, 1000));//随机休息一下 return this.GetRandomNumber(min, max); } /// <summary> /// 获取随机数,解决重复问题 /// </summary> /// <param name="min"></param> /// <param name="max"></param> /// <returns></returns> public int GetRandomNumber(int min, int max) { Guid guid = Guid.NewGuid();//每次都是全新的ID string sGuid = guid.ToString(); int seed = DateTime.Now.Millisecond; for (int i = 0; i < sGuid.Length; i++) { switch (sGuid[i]) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': seed = seed + 1; break; case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': seed = seed + 2; break; case 'o': case 'p': case 'q': case 'r': case 's': case 't': seed = seed + 3; break; case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': seed = seed + 3; break; default: seed = seed + 4; break; } } Random random = new Random(seed); return random.Next(min, max); } }
UI 开始、结束数据处理
#region UI /// <summary> /// 点击开始: /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, EventArgs e) { try { #region 初始化动作 this.btnStart.Text = "运行ing"; this.btnStart.Enabled = false; this.IsGoOn = true; this.taskList = new List<Task>(); this.lblBlue.Text = "00"; this.lblRed1.Text = "00"; this.lblRed2.Text = "00"; this.lblRed3.Text = "00"; this.lblRed4.Text = "00"; this.lblRed5.Text = "00"; this.lblRed6.Text = "00"; #endregion Thread.Sleep(1000); foreach (var control in this.gboSSQ.Controls) { if (control is Label) { Label label = (Label)control; if (label.Name.Contains("Blue")) { taskList.Add(Task.Run(() => { try { while (IsGoOn) { //1 获取随机数 int index = new RandomHelper().GetRandomNumberDelay(0, 16); string sNumber = this.BlueNums[index]; //2 更新界面 //this.lblBlue.Text = sNumber; //子线程不能操作控件,委托给主线程操作 //this.Invoke this.Invoke(new Action(() => { label.Text = sNumber; })); //3 循环 } } catch (Exception ex) { Console.WriteLine(ex.Message); } })); } else if (label.Name.Contains("Red")) { taskList.Add(Task.Run(() => { try { while (IsGoOn) { int index = new RandomHelper().GetRandomNumberDelay(0, 33); string sNumber = this.RedNums[index]; //可能重复 得去重 //1 过河的卒子 一次性拿6个,一次更新,但是界面更新有规律 //2 再来个数组标记一下,有点笨拙;其实界面不就有吗? //3 80奋斗 数据分隔,安全高效,但是有规律 //检测下是否重复, 直接比对界面 //获取随机 比对界面 更新 lock (SSQ_Lock) { List<string> usedNumberList = this.GetUsedRedNumbers(); if (!usedNumberList.Contains(sNumber)) { this.Invoke(new Action(() => { //Thread.Sleep(10); label.Text = sNumber; }));//实际上是同步的 } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } })); } } } Task.Factory.ContinueWhenAll(this.taskList.ToArray(), tArray => { this.ShowResult(); this.Invoke(new Action(() => { this.btnStart.Enabled = true; this.btnStop.Enabled = false; })); }); Task.Delay(10 * 1000).ContinueWith(t => { this.Invoke(new Action(() => { this.btnStop.Enabled = true; })); }); } catch (Exception ex) { Console.WriteLine("双色球启动出现异常:{0}", ex.Message); } } private static readonly object SSQ_Lock = new object(); private List<string> GetUsedRedNumbers() { List<string> usedNumberList = new List<string>(); foreach (var controler in this.gboSSQ.Controls) { if (controler is Label) { if (((Label)controler).Name.Contains("Red")) { usedNumberList.Add(((Label)controler).Text); } } } //if (usedNumberList.Distinct<string>().Count() < 6) //{ // usedNumberList.ForEach(s => Console.WriteLine($"This is {s}")); //} return usedNumberList; } /// <summary> /// 点击结束 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStop_Click(object sender, EventArgs e) { this.IsGoOn = false; //Thread.Sleep(5 * 1000);//不要这样等待 //Task.Run(() =>//不止直接waitall 会死锁 //{ // Task.WaitAll(this.taskList.ToArray()); // this.ShowResult(); //}); } /// <summary> /// 弹框提示数据 /// </summary> private void ShowResult() { MessageBox.Show(string.Format("本期双色球结果为:{0} {1} {2} {3} {4} {5} 蓝球{6}" , this.lblRed1.Text , this.lblRed2.Text , this.lblRed3.Text , this.lblRed4.Text , this.lblRed5.Text , this.lblRed6.Text , this.lblBlue.Text)); } #endregion
付费内容,请联系本人QQ:1002453261
本文来自博客园,作者:明志德道,转载请注明原文链接:https://www.cnblogs.com/for-easy-fast/articles/12454722.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析