• async/await,多线程实现双色球


      1,async/await

      1     /// <summary>
      2     /// await/async关键字
      3     /// </summary>
      4     public class AwaitAsyncShow
      5     {
      6         public static void TestShow()
      7         {
      8             Test();
      9         }
     10 
     11 
     12         private async static Task Test()
     13         {
     14             Console.WriteLine($"当前主线程id={Thread.CurrentThread.ManagedThreadId}");
     15             {
     16                 //NoReturnNoAwait();
     17             }
     18             {
     19                 //NoReturn();
     20                 //for (int i = 0; i < 10; i++)
     21                 //{
     22                 //    Thread.Sleep(300);
     23                 //    Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId} i={i}");
     24                 //}
     25             }
     26             {
     27                 Task t = NoReturnTask();
     28                 Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
     29                 t.Wait();//主线程等待Task的完成
     30                 //await t;//await后的代码会由子线程执行
     31             }
     32             {
     33                 Task<long> t = SumAsync();
     34                 Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
     35                 long lResult = t.Result;//访问result   主线程等待Task的完成
     36                 t.Wait();//等价于上一行
     37             }
     38             {
     39                 //Task<int> t = SumFactory();
     40                 //Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
     41                 //long lResult = t.Result;//没有await和async 普通的task
     42                 //t.Wait();
     43             }
     44             //Console.WriteLine($"Test Sleep Start {Thread.CurrentThread.ManagedThreadId}");
     45             //Thread.Sleep(10000);
     46             //Console.WriteLine($"Test Sleep End {Thread.CurrentThread.ManagedThreadId}");
     47             //Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
     48             Console.Read();
     49         }
     50 
     51 
     52         /// <summary>
     53         /// 只有async没有await,会有个warn
     54         /// 跟普通方法没有区别
     55         /// </summary>
     56         private static async void NoReturnNoAwait()
     57         {
     58             //主线程执行
     59             Console.WriteLine($"NoReturnNoAwait Sleep before Task,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     60             Task task = Task.Run(() =>//启动新线程完成任务
     61             {
     62                 Console.WriteLine($"NoReturnNoAwait Sleep before,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     63                 Thread.Sleep(3000);
     64                 Console.WriteLine($"NoReturnNoAwait Sleep after,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     65             });
     66 
     67             //主线程执行
     68             Console.WriteLine($"NoReturnNoAwait Sleep after Task,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     69         }
     70 
     71         /// <summary>
     72         /// async/await 
     73         /// 不能单独await
     74         /// await 只能放在task前面
     75         /// 不推荐void返回值,使用Task来代替
     76         /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。Async Void 不行
     77         /// </summary>
     78         private static async void NoReturn()
     79         {
     80             //主线程执行
     81             Console.WriteLine($"NoReturn Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     82             TaskFactory taskFactory = new TaskFactory();
     83             Task task = taskFactory.StartNew(() =>
     84             {
     85                 Console.WriteLine($"NoReturn Sleep before,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     86                 Thread.Sleep(3000);
     87                 Console.WriteLine($"NoReturn Sleep after,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     88             });
     89             await task;//主线程到这里就返回了,执行主线程任务
     90 
     91             //一流水儿的写下去的,耗时任务就用await
     92 
     93             //子线程执行   其实是封装成委托,在task之后成为回调(编译器功能  状态机实现)
     94             //task.ContinueWith()
     95             //这个回调的线程是不确定的:可能是主线程  可能是子线程  也可能是其他线程
     96             Console.WriteLine($"NoReturn Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
     97         }
     98 
     99         /// <summary>
    100         /// 无返回值  async Task == async void
    101         /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。Async Void 不行
    102         /// </summary>
    103         /// <returns></returns>
    104         private static async Task NoReturnTask()
    105         {
    106             //这里还是主线程的id
    107             Console.WriteLine($"NoReturnTask Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
    108 
    109             await Task.Run(() =>
    110             {
    111                 Console.WriteLine($"NoReturnTask Sleep before,ThreadId={Thread.CurrentThread.ManagedThreadId}");
    112                 Thread.Sleep(3000);
    113                 Console.WriteLine($"NoReturnTask Sleep after,ThreadId={Thread.CurrentThread.ManagedThreadId}");
    114             });
    115             //await task;
    116             Console.WriteLine($"NoReturnTask Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}");
    117 
    118 
    119             //return new TaskFactory().StartNew(() => { });  //不能return  没有async才行
    120         }
    121 
    122         /// <summary>
    123         /// 带返回值的Task  
    124         /// 要使用返回值就一定要等子线程计算完毕
    125         /// </summary>
    126         /// <returns>async 就只返回long</returns>
    127         private static async Task<long> SumAsync()
    128         {
    129             Console.WriteLine($"SumAsync 111 start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
    130             long result = 0;
    131 
    132             await Task.Run(() =>
    133             {
    134                 for (int k = 0; k < 10; k++)
    135                 {
    136                     Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
    137                     Thread.Sleep(1000);
    138                 }
    139 
    140                 for (long i = 0; i < 999999999; i++)
    141                 {
    142                     result += i;
    143                 }
    144             });
    145             Console.WriteLine($"SumFactory 111   end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
    146             return result;
    147         }
    148 
    149         /// <summary>
    150         /// 真的返回Task  不是async  
    151         /// 
    152         /// 要使用返回值就一定要等子线程计算完毕
    153         /// </summary>
    154         /// <returns>没有async Task</returns>
    155         private static Task<int> SumFactory()
    156         {
    157             Console.WriteLine($"SumFactory 111 start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
    158             TaskFactory taskFactory = new TaskFactory();
    159             Task<int> iResult = taskFactory.StartNew<int>(() =>
    160             {
    161                 Thread.Sleep(3000);
    162                 Console.WriteLine($"SumFactory 123 Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
    163                 return 123;
    164             });
    165             //Console.WriteLine($"This is {iResult.Result}");
    166             Console.WriteLine($"SumFactory 111   end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
    167             return iResult;
    168         }
    169     }
    View Code

      2,多线程实现双色球

      方式1

      1     /// <summary>
      2     /// 多线程双色球项目:
      3     /// 双色球:投注号码由6个红色球号码和1个蓝色球号码组成。
      4     /// 红色球号码从01--33中选择
      5     /// 蓝色球号码从01--16中选择
      6     /// </summary>
      7     public partial class frmSSQ : Form
      8     {
      9         public frmSSQ()
     10         {
     11             InitializeComponent();
     12 
     13             this.btnStart.Enabled = true;
     14             this.btnStop.Enabled = false;
     15         }
     16 
     17         #region Data 
     18         /// <summary>
     19         /// 红球集合
     20         /// </summary>
     21         private string[] RedNums =
     22         {
     23             "01","02","03","04","05","06","07","08","09","10",
     24             "11","12","13","14","15","16","17","18","19","20",
     25             "21","22","23","24","25","26","27","28","29","30",
     26             "31","32","33"
     27         };
     28 
     29         /// <summary>
     30         /// 蓝球集合
     31         /// </summary>
     32         private string[] BlueNums =
     33         {
     34             "01","02","03","04","05","06","07","08","09","10",
     35             "11","12","13","14","15","16"
     36         };
     37 
     38 
     39         private static object _Lock = new object();
     40 
     41         private bool IsGoon = true;
     42         #endregion
     43 
     44         #region UI
     45         /// <summary>
     46         /// 点击开始:
     47         /// </summary>
     48         /// <param name="sender"></param>
     49         /// <param name="e"></param>
     50         private void btnStart_Click(object sender, EventArgs e)
     51         {
     52             try
     53             {
     54                 this.btnStart.Text = "开始ing";
     55                 this.btnStart.Enabled = false;
     56                 this.IsGoon = true;
     57                 foreach (var item in this.gboSSQ.Controls)
     58                 {
     59                     if (item is Label)
     60                     {
     61                         ((Label)item).Text = "00";
     62                     }
     63                 }
     64                 Thread.Sleep(1000);
     65 
     66                 TaskFactory taskFactory = new TaskFactory();
     67                 List<Task> taskList = new List<Task>();
     68                 foreach (var item in this.gboSSQ.Controls)
     69                 {
     70                     if (item is Label)
     71                     {
     72                         Label lbl = item as Label;
     73                         taskList.Add(taskFactory.StartNew(() =>
     74                        {
     75                            while (this.IsGoon)
     76                            {
     77                                string text = "";
     78                                if (lbl.Name.Contains("Red"))
     79                                {
     80                                    //1 解决冲突的最好办法,是没有冲突,上来就随机分6组,每个线程只取一个组的
     81                                    //2 线程安全的集合,出一个进一个
     82                                    //3 每次先找出6个不同的球,然后分配给线程
     83                                    //4 每次线程随意获取球,更新前检测下有没有冲突,有则重新随机,没有则更新
     84                                    text = this.GetRandomText();
     85                                    lock (_Lock)
     86                                    {
     87                                        List<string> redList = this.GetUsedRed(lbl);
     88                                        if (redList.Contains(text))
     89                                            continue;
     90                                        else
     91                                        {
     92                                            Thread.Sleep(50);//让停止的时候,线程可能在这里
     93                                            this.UpdateLable(lbl, text);
     94                                        }
     95                                    }
     96                                }
     97                                else
     98                                {
     99                                    int index = RandomHelper.GetRandomNumber(0, 16);
    100                                    //Random random = new Random();//伪随机
    101                                    //string text = this.BlueNums[random.Next(0, 15)];
    102                                    //int index = RandomHelper.GetRandomNumber(0, 16);
    103                                    text = this.BlueNums[index];
    104                                    //lbl.Text = text;//不行
    105                                    this.UpdateLable(lbl, text);
    106                                }
    107 
    108                                //this.UpdateLable(lbl, text);
    109                                Thread.Sleep(50);
    110                            }
    111                        }));
    112                     }
    113                 }
    114                 taskFactory.ContinueWhenAll(taskList.ToArray(), tList => this.ShowResult());
    115 
    116 
    117                 this.btnStop.Enabled = true;//正确的时机打开:所有的求都不是0再true
    118             }
    119             catch (Exception ex)
    120             {
    121                 Console.WriteLine("双色球启动出现异常:{0}", ex.Message);
    122             }
    123         }
    124 
    125         /// <summary>
    126         /// 点击结束
    127         /// </summary>
    128         /// <param name="sender"></param>
    129         /// <param name="e"></param>
    130         private void btnStop_Click(object sender, EventArgs e)
    131         {
    132             this.btnStart.Enabled = true;
    133             this.btnStop.Enabled = false;
    134             this.IsGoon = false;
    135             //this.ShowResult();
    136         }
    137 
    138         /// <summary>
    139         /// 弹框提示数据
    140         /// </summary>
    141         private void ShowResult()
    142         {
    143             MessageBox.Show(string.Format("本期双色球结果为:{0} {1} {2} {3} {4} {5}  蓝球{6}"
    144                 , this.lblRed1.Text
    145                 , this.lblRed2.Text
    146                 , this.lblRed3.Text
    147                 , this.lblRed4.Text
    148                 , this.lblRed5.Text
    149                 , this.lblRed6.Text
    150                 , this.lblBlue.Text));
    151         }
    152         #endregion
    153 
    154         #region PrivateMethod
    155         private void UpdateLable(Label label, string text)
    156         {
    157             this.Invoke(new Action(() =>
    158             {
    159                 label.Text = text;
    160             }));
    161         }
    162 
    163         private string GetRandomText()
    164         {
    165             int index = RandomHelper.GetRandomNumber(0, 33);
    166             return this.RedNums[index];
    167         }
    168 
    169         private List<string> GetUsedRed(Label lbl)
    170         {
    171             List<string> usedList = new List<string>();
    172             foreach (var labItem in this.gboSSQ.Controls)
    173             {
    174                 if (labItem is Label && labItem != lbl)//当前的数字可以用
    175                 {
    176                     usedList.Add(((Label)labItem).Text);
    177                 }
    178             }
    179             return usedList;
    180         }
    181 
    182         #endregion
    183     }
    View Code

      方式2

      1     /// <summary>
      2     /// 双色球:投注号码由6个红色球号码和1个蓝色球号码组成。
      3     /// 红色球号码从01--33中选择
      4     /// 蓝色球号码从01--16中选择
      5     /// </summary>
      6     public partial class Form1 : Form
      7     {
      8         public Form1()
      9         {
     10             InitializeComponent();
     11             this.btnStop.Enabled = false;
     12         }
     13 
     14         #region
     15         /// <summary>
     16         /// 红球集合
     17         /// </summary>
     18         private string[] RedNums =
     19         {
     20             "01","02","03","04","05","06","07","08","09","10",
     21             "11","12","13","14","15","16","17","18","19","20",
     22             "21","22","23","24","25","26","27","28","29","30",
     23             "31","32","33"
     24         };
     25 
     26         /// <summary>
     27         /// 蓝球集合
     28         /// </summary>
     29         private string[] BlueNums =
     30         {
     31             "01","02","03","04","05","06","07","08","09","10",
     32             "11","12","13","14","15","16"
     33         };
     34         private bool isGoon = true;
     35         #endregion
     36 
     37         /// <summary>
     38         /// 开始
     39         /// </summary>
     40         /// <param name="sender"></param>
     41         /// <param name="e"></param>
     42         private void btnStart_Click(object sender, EventArgs e)
     43         {
     44             try
     45             {
     46                 this.btnStart.Text = "开始ing";
     47                 this.btnStart.Enabled = false;
     48                 this.isGoon = true;
     49                 this.lblBlue.Text = "00";
     50                 this.lblRed1.Text = "00";
     51                 this.lblRed2.Text = "00";
     52                 this.lblRed3.Text = "00";
     53                 this.lblRed4.Text = "00";
     54                 this.lblRed5.Text = "00";
     55                 this.lblRed6.Text = "00";
     56                 Thread.Sleep(1000);
     57                 this.btnStop.Enabled = true;//合适打开
     58 
     59                 List<Task> taskList = new List<Task>();
     60                 TaskFactory taskFactory = new TaskFactory();
     61                 foreach (Control c in this.gboSSQ.Controls)
     62                 {
     63                     if (c is Label)
     64                     {
     65                         Label lbl = (Label)c;
     66                         taskList.Add(taskFactory.StartNew(() =>
     67                         {
     68                             while (isGoon)
     69                             {
     70                                 string text = this.GetNum(lbl);//获取num
     71                                 this.UpdateLbl(lbl, text);//更新界面
     72                             }
     73                             //Console.WriteLine("线程完成");
     74                         }));
     75                     }
     76                 }
     77 
     78                 taskFactory.ContinueWhenAll(taskList.ToArray(), t =>
     79                 {
     80                     MessageShow();
     81                 });
     82             }
     83             catch (Exception ex)
     84             {
     85                 Console.WriteLine("双色球出现异常:{0}", ex.Message);
     86             }
     87         }
     88 
     89         /// <summary>
     90         /// 结束
     91         /// </summary>
     92         /// <param name="sender"></param>
     93         /// <param name="e"></param>
     94         private void btnStop_Click(object sender, EventArgs e)
     95         {
     96             this.btnStop.Enabled = false;
     97             this.btnStart.Enabled = true;
     98             btnStart.Text = "开始";
     99             this.isGoon = false;
    100 
    101         }
    102 
    103         /// <summary>
    104         /// 打印结果
    105         /// </summary>
    106         private void MessageShow()
    107         {
    108             MessageBox.Show(string.Format("本期双色球结果是 {0} {1} {2} {3} {4} {5}  {6}",
    109                    lblRed1.Text, lblRed2.Text, lblRed3.Text, lblRed4.Text, lblRed5.Text, lblRed6.Text, lblBlue.Text));
    110         }
    111 
    112         private static object GetNum_Lock = new object();
    113 
    114         /// <summary>
    115         /// 获取num
    116         /// </summary>
    117         /// <param name="label"></param>
    118         /// <returns></returns>
    119         private string GetNum(Label label)
    120         {
    121             Thread.Sleep(1000);//让电脑轻松一点,可以随意切换线程
    122             if (label.Name.Equals("lblBlue"))
    123             {
    124                 return this.BlueNums[new Random().Next(0, this.BlueNums.Length - 1)];//0到15
    125             }
    126             else
    127             {
    128                 //33选6
    129                 string text = this.RedNums[new Random().Next(0, this.RedNums.Length - 1)];//0到32
    130                 lock (GetNum_Lock)
    131                 {
    132                     List<string> usedNumList = this.GetUsedNums();
    133                     while (usedNumList.Contains(text))
    134                     {
    135                         text = this.RedNums[new Random().Next(0, this.RedNums.Length - 1)];//0到32
    136                     }
    137                     return text;
    138                 }
    139 
    140             }
    141         }
    142 
    143         /// <summary>
    144         /// 获取当前界面上的球号码
    145         /// </summary>
    146         /// <returns></returns>
    147         private List<string> GetUsedNums()
    148         {
    149             List<string> usedNumList = new List<string>();
    150             foreach (Control c in this.gboSSQ.Controls)
    151             {
    152                 if (c is Label && ((Label)c).Name.Contains("Red"))
    153                 {
    154                     usedNumList.Add(((Label)c).Text);
    155                 }
    156             }
    157             return usedNumList;
    158         }
    159 
    160         /// <summary>
    161         /// 更新界面
    162         /// </summary>
    163         /// <param name="lbl"></param>
    164         /// <param name="text"></param>
    165         private void UpdateLbl(Label lbl, string text)
    166         {
    167             if (lbl.InvokeRequired)
    168             {
    169                 this.Invoke(new Action(() => lbl.Text = text));//交给UI线程去更新
    170             }
    171             else
    172             {
    173                 lbl.Text = text;
    174             }
    175         }
    176 
    177     }
    View Code

  • 相关阅读:
    使用thinkphp连接sqlserver数据库时提示“系统不支持:sqlsrv”
    ThinkPHP连接sql server数据库
    帝国cms常用变量总结
    帝国CMS常见问题记录
    帝国CMS商城功能高级使用
    帝国CMS 6.0功能解密之新版结合项功能,帝国结合项使用
    CSS媒体查询,CSS根据不同的分辨率显示不同的样式
    使用phpstuby时,Apache或mysql无法启动,端口被占用
    火狐firefox提示“内容编码错误 无法显示您尝试查看的页面,因为它使用了无效或者不支持的压缩格式。”
    js跳转页面方法整理
  • 原文地址:https://www.cnblogs.com/shangec/p/9821927.html
Copyright © 2020-2023  润新知