c# 多线程编程实际应用-winform实现简易的双色球

需求:

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

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

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

设计逻辑

点击开始按钮:7个球就应该变化

点击开始,都在变化,每一个都相互没有影响,每个球之间没有任何规律

要求每个球的变化:要相互不影响;完全独立---多线程的特点:多线程就是每个线程是完全独立的,相互没有影响的;

开始:

一、多线程完成

1、七个球->7个线程

2、每个线程负责一个球的不断变换

二、如何去变化

1.开启线程

2.在这个线程内部---要在需求指定的球号码所在范围内;取值

3.赋值给球

4.要不断的变化---循环---不断的取值,赋值--(不断的变)

三、重复怎么解决?

1.在赋值的时候,先判断一下,如果重复,再生成一个,重新去赋值;

2.加锁

四、开奖

1.应该让循环变化的球要停止下来

2.把界面上所有的球号码弹出来

代码部分
1、frmSSQ.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StudyThread
{
    public partial class FrmSSQ : Form
    {
        /// <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 readonly static object _lock = new object();
        private bool IsGon = true;
        private List<Task> tasks = new List<Task>();
        public FrmSSQ()
        {
            InitializeComponent();
        }

        private void btnstart_Click(object sender, EventArgs e)
        {
            // 初始化
            tasks = new List<Task>();
            this.btnstart.Text = "正在开始...";
            this.btnstart.Enabled = false;
            this.btnstop.Enabled = true;
            // 把7个球都重置为00
            this.labelBlue1.Text = "00";
            this.labelRed1.Text = "00";
            this.labelRed2.Text = "00";
            this.labelRed3.Text = "00";
            this.labelRed4.Text = "00";
            this.labelRed5.Text = "00";
            this.labelRed6.Text = "00";

            foreach (var control in this.gboSSQ.Controls)
            {
                if(control is Label)
                {
                    Label label = (Label)control;
                    tasks.Add(Task.Run(() =>
                    {
                        if(label.Name.Contains("Blue")) // 蓝色球
                        {
                            // BlueNums中取数据;通过索引来取
                            //随机的取: 随机的获取索引 
                            while(IsGon)
                            {
                                // 索引最大是16
                                var index = new RandomHelper().GetRandomNumber(0, 16); 
                                string num = BlueNums[index];
                                this.Invoke(new Action(() =>
                                {
                                    label.Text = num;
                                }));
                            }
                        }
                        else // 红色球
                        {
                            while(IsGon)
                            {
                                // 索引最大是22
                                var index = new RandomHelper().GetRandomNumber(0, 33); 
                                string num = RedNums[index];
                                // 赋值之前可以先判断一下,如果有重复的就过去,在循环
                                // 获取当前界面的所有红色球
                                lock (_lock)
                                {
                                    // 获取重复值
                                    var list = this.getCurNums();
                                    if(!list.Contains(num))
                                    {
                                        //只要是判断了,还是会重复
                                        //是在多线程中,委托一个动作让主线程去帮助完成 
                                        this.Invoke(new Action(() =>
                                        {
                                            label.Text = num;
                                        }));
                                    }
                                }
                            }
                        }
                    }));
                }
            }

            // Task.Factory.ContinueWhenAll 创建了一个新任务 continuationTask。这个新任务在 tasks 数组中的所有任务都完成时执行。

            Task.Factory.ContinueWhenAll(tasks.ToArray(), ts =>
            {
                this.Invoke(new Action(() =>
                {
                    this.showResult();
                    this.IsGon = true;
                    this.btnstart.Text = "开始";
                    this.btnstart.Enabled = true;
                    this.btnstop.Enabled = false;
                }));
            });
        }

        private void btnstop_Click(object sender, EventArgs e)
        {
            // 停止
            this.IsGon = false;
            // Task.WaitAll(tasks.ToArray());//  这里会有问题,死锁:主线程和子线程相互等待了: 主线程要等待所有的子线程执行结束;子线程中,赋值问题要交给主线程去完成;形成了相互等待;
            //Task.Run(() =>
            //{
            //    Task.WaitAll(tasks.ToArray());
            //    showResult();
            //});

        }
        private List<string> getCurNums()
        {
            var list = new List<string>();
            foreach (var controls in this.gboSSQ.Controls)
            {
                if (controls is Label)
                {
                    var label = (Label)controls;
                    if (label.Name.Contains("Red"))
                    {
                        list.Add(label.Text);
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 弹框提示数据
        /// </summary>
        private void showResult()
        {
            MessageBox.Show(string.Format("本期双色球结果为:{0} {1} {2} {3} {4} {5}  蓝球{6}"
                , this.labelRed1.Text
                , this.labelRed2.Text
                , this.labelRed3.Text
                , this.labelRed4.Text
                , this.labelRed5.Text
                , this.labelRed6.Text
                , this.labelBlue1.Text));
        }
    }
}


2、FrmSSQ.Designer.cs

namespace StudyThread
{
    partial class FrmSSQ
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            gboSSQ = new GroupBox();
            btnstop = new Button();
            btnstart = new Button();
            labelBlue1 = new Label();
            labelRed6 = new Label();
            labelRed5 = new Label();
            labelRed4 = new Label();
            labelRed3 = new Label();
            labelRed2 = new Label();
            labelRed1 = new Label();
            gboSSQ.SuspendLayout();
            SuspendLayout();
            // 
            // gboSSQ
            // 
            gboSSQ.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
            gboSSQ.Controls.Add(btnstop);
            gboSSQ.Controls.Add(btnstart);
            gboSSQ.Controls.Add(labelBlue1);
            gboSSQ.Controls.Add(labelRed6);
            gboSSQ.Controls.Add(labelRed5);
            gboSSQ.Controls.Add(labelRed4);
            gboSSQ.Controls.Add(labelRed3);
            gboSSQ.Controls.Add(labelRed2);
            gboSSQ.Controls.Add(labelRed1);
            gboSSQ.Location = new Point(37, 12);
            gboSSQ.Name = "gboSSQ";
            gboSSQ.Size = new Size(944, 623);
            gboSSQ.TabIndex = 0;
            gboSSQ.TabStop = false;
            gboSSQ.Text = "gboSSQ";
            // 
            // btnstop
            // 
            btnstop.Location = new Point(209, 292);
            btnstop.Name = "btnstop";
            btnstop.Size = new Size(112, 34);
            btnstop.TabIndex = 8;
            btnstop.Text = "停止";
            btnstop.UseVisualStyleBackColor = true;
            btnstop.Click += btnstop_Click;
            // 
            // btnstart
            // 
            btnstart.Location = new Point(6, 292);
            btnstart.Name = "btnstart";
            btnstart.Size = new Size(112, 34);
            btnstart.TabIndex = 7;
            btnstart.Text = "开始";
            btnstart.UseVisualStyleBackColor = true;
            btnstart.Click += btnstart_Click;
            // 
            // labelBlue1
            // 
            labelBlue1.AutoSize = true;
            labelBlue1.Location = new Point(17, 128);
            labelBlue1.Name = "labelBlue1";
            labelBlue1.Size = new Size(32, 24);
            labelBlue1.TabIndex = 6;
            labelBlue1.Text = "00";
            // 
            // labelRed6
            // 
            labelRed6.AutoSize = true;
            labelRed6.Location = new Point(512, 54);
            labelRed6.Name = "labelRed6";
            labelRed6.Size = new Size(32, 24);
            labelRed6.TabIndex = 5;
            labelRed6.Text = "00";
            // 
            // labelRed5
            // 
            labelRed5.AutoSize = true;
            labelRed5.Location = new Point(414, 54);
            labelRed5.Name = "labelRed5";
            labelRed5.Size = new Size(32, 24);
            labelRed5.TabIndex = 4;
            labelRed5.Text = "00";
            // 
            // labelRed4
            // 
            labelRed4.AutoSize = true;
            labelRed4.Location = new Point(307, 54);
            labelRed4.Name = "labelRed4";
            labelRed4.Size = new Size(32, 24);
            labelRed4.TabIndex = 3;
            labelRed4.Text = "00";
            // 
            // labelRed3
            // 
            labelRed3.AutoSize = true;
            labelRed3.Location = new Point(209, 54);
            labelRed3.Name = "labelRed3";
            labelRed3.Size = new Size(32, 24);
            labelRed3.TabIndex = 2;
            labelRed3.Text = "00";
            // 
            // labelRed2
            // 
            labelRed2.AutoSize = true;
            labelRed2.Location = new Point(115, 54);
            labelRed2.Name = "labelRed2";
            labelRed2.Size = new Size(32, 24);
            labelRed2.TabIndex = 1;
            labelRed2.Text = "00";
            // 
            // labelRed1
            // 
            labelRed1.AutoSize = true;
            labelRed1.Location = new Point(17, 54);
            labelRed1.Name = "labelRed1";
            labelRed1.Size = new Size(32, 24);
            labelRed1.TabIndex = 0;
            labelRed1.Text = "00";
            // 
            // FrmSSQ
            // 
            AutoScaleDimensions = new SizeF(11F, 24F);
            AutoScaleMode = AutoScaleMode.Font;
            ClientSize = new Size(1015, 647);
            Controls.Add(gboSSQ);
            Name = "FrmSSQ";
            Text = "FrmSSQ";
            gboSSQ.ResumeLayout(false);
            gboSSQ.PerformLayout();
            ResumeLayout(false);
        }

        #endregion

        private GroupBox gboSSQ;
        private Label labelRed1;
        private Label labelRed2;
        private Label labelRed4;
        private Label labelRed3;
        private Label labelRed6;
        private Label labelRed5;
        private Label labelBlue1;
        private Button btnstart;
        private Button btnstop;
    }
}

3、RandomHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StudyThread
{
    public class RandomHelper
    {

        /// <summary>
        /// 获取随机数,解决重复问题
        /// </summary>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        public int GetRandomNumber(int min, int max)
        {
            Guid guid = Guid.NewGuid();//每次都是全新的ID  全球唯一Id
            string sGuid = guid.ToString();
            int seed = DateTime.Now.Millisecond;
            //保证seed 在同一时刻 是不相同的
            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);
        }
    }
}
 

实现效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值