.NET异步和多线程系列(五)- 多线程双色球项目

  • A+
所属分类:.NET技术
摘要

本文是.NET异步和多线程系列的第五章,本章将综合之前分享的异步和多线程来实现简单的双色球项目。

本文是.NET异步和多线程系列的第五章,本章将综合之前分享的异步和多线程来实现简单的双色球项目。

话不多说,下面我们直接进入本章主题。

首先我们来看下需求分析:

  双色球:投注号码由6个红色球号码和1个蓝色球号码组成。

  红色球号码:从01--33中选择,不重复。

  蓝色球号码:从01--16中选择。

  球号码随机的规则:远程获取一个随机数据,这个会有较长的时间损耗。

双色球项目界面设计如下:

.NET异步和多线程系列(五)- 多线程双色球项目

接下来我们重点来看下代码:

模拟获取远程随机数:

using System; using System.Threading;  namespace MyLottery.Common {     /// <summary>     /// 解决随机数重复问题     /// 同时模拟远程请求的随机延时     /// </summary>     public class RandomHelper     {         /// <summary>         /// 随机获取数字并等待一段时间         /// </summary>         public int GetRandomNumberDelay(int min, int max)         {             Thread.Sleep(this.GetRandomNumber(500, 1000)); //随机休息一下             return this.GetRandomNumber(min, max);         }          /// <summary>         /// 获取随机数(解决重复问题)         /// </summary>         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);         }     } }

界面核心代码如下:

using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;  using MyLottery.Common;  namespace MyLottery {     /// <summary>     /// 多线程双色球项目     /// 需求:     ///     双色球:投注号码由6个红色球号码和1个蓝色球号码组成。     ///     红色球号码:从01--33中选择,不重复。     ///     蓝色球号码:从01--16中选择。     ///      /// 球号码随机的规则:远程获取一个随机数据,这个会有较长的时间损耗。     /// </summary>     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();             this.btnStart.Enabled = true;             this.btnStop.Enabled = false;         }          #region 字段和属性          #region 数据           /// <summary>         /// 红球集合  其实可以写入配置文件         /// </summary>         public 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"         };          #endregion 数据          private bool _isGoOn = true;         private List<Task> _taskList = new List<Task>();         private static readonly object _lockObj = new object();          #endregion 字段和属性          /// <summary>         /// 点击开始         /// </summary>         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.ToString());                                 }                             }));                         }                         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];                                         //可能重复  得去重                                         //检测下是否重复,直接比对界面                                         //获取随机   比对界面   更新                                         lock (_lockObj)                                         {                                             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.ToString());             }         }          /// <summary>         /// 点击结束         /// </summary>         private void btnStop_Click(object sender, EventArgs e)         {             this._isGoOn = false;              #region 死锁              //此处主线程不能直接WaitAll 界面会卡死 死锁了             //主线程要等着子线程完成后才能往下走,而子线程又要等着主线程帮忙干件事后才能往下走,两者都在等着对方,这就导致了死锁。             //{             //    Task.WaitAll(this._taskList.ToArray());             //    this.ShowResult();             //}              #endregion 死锁              #region ShowResult这事情在这里做不合适,应该放到回调里面去做比较合适              //此处要等子线程完成的话应该再开一个子线程去等才对             //{             //    Task.Run(() =>             //    {             //        Task.WaitAll(this._taskList.ToArray());             //        this.ShowResult();             //    });             //}              #endregion ShowResult这事情在这里做不合适,应该放到回调里面去做比较合适         }          #region 公共方法          /// <summary>         /// 获取已经使用过的红色数字         /// </summary>         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);                     }                 }             }             return usedNumberList;         }          /// <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 公共方法     } }

运行结果如下:

.NET异步和多线程系列(五)- 多线程双色球项目

 

Demo源码:

链接:https://pan.baidu.com/s/1J2OFDxI4dHspkrh9CJy2Sg  提取码:h2l3

此文由博主精心撰写转载请保留此原文链接:https://www.cnblogs.com/xyh9039/p/13616391.html

版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!