多线程使用

同步、异步、并发、异步回调的使用。

通过查询书籍名称,并打印出来为例子讲解, 使用winform,设计“同步执行”、“”异步执行“、“并发执行””、“异步回调”按钮,和一个textbox显示框

   /// <summary>
        /// 同步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_sync_Click(object sender, EventArgs e)
        {
            Stopwatch sw =Stopwatch.StartNew();
            resultTextBox.Clear();
            AppendLine("同步检索开始……"); 
             int idx = 0;
            Data.Books.ForEach(x => AppendLine($"{++idx}.{x.Search()}"));
            sw.Stop();
            AppendLine($"同步检索完成:{Convert.ToSingle(sw.ElapsedMilliseconds)/1000}秒");
        }
        /// <summary>
        /// 异步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btn_asyn_Click(object sender, EventArgs e)
        {
            Stopwatch sw =Stopwatch.StartNew();
            resultTextBox.Clear();
            AppendLine("异步检索开始……");
                int idx = 0;
            foreach (var book in Data.Books)
            {
                var task = await Task.Run(book.Search).ConfigureAwait(false);   //为了使返回时进入线程池来执行后续方法  提高效率
                AppendLineThread($"{++idx}.{task}");

            }
            sw.Stop();
            AppendLineThread($"异步检索完成:{Convert.ToSingle((sw.ElapsedMilliseconds) / 1000)}秒");
        }
        /// <summary>
        /// 并发   异步解决了卡UI线程问题 但不能提高效率
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void byn_concu_Click(object sender, EventArgs e)
        {
            Stopwatch sw = Stopwatch.StartNew();
            resultTextBox.Clear();
            AppendLine("并行检索开始……");
            int idx = 0;

            List<Task<string>> Tasks = new();  //线程集合,

            Data.Books.ForEach(x=>Tasks.Add(Task.Run(x.Search)));  //  线程返回值string 
            var tasks=await Task.WhenAll(Tasks); //当所有的线程都运行完之后
            foreach (var result in tasks)
            {
                AppendLine($"{++idx}.{result}");
            }
            sw.Stop();
            AppendLine($"并行检索完成:{Convert.ToSingle((sw.ElapsedMilliseconds) / 1000)}秒");

        }
        private void AppendLine(string text)
        {
            resultTextBox.AppendText(string.IsNullOrEmpty(resultTextBox.Text)?text:$"{Environment.NewLine}{text}");
            resultTextBox.ScrollToCaret();
            resultTextBox.Refresh();
        }
  
        /// <summary>
        /// 异步回调  线程哪一个先结束,继续往下执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_AsyncCallback_Click(object sender, EventArgs e)
        {
            Stopwatch sw = Stopwatch.StartNew();
            resultTextBox.Clear();
            AppendLine("异步回调检索开始……");
            int idx = 0;
            foreach (var book in Data.Books)
            {
                Task.Run(book.Search).ContinueWith(t => AppendLineThread($"{++idx}.{t.Result}"));   //Ui线程在此处没有等待,所以没有办法等到所有线程都执行完
            }
            sw.Stop();
            AppendLine($"异步回调检索完成:{Convert.ToSingle(sw.ElapsedMilliseconds) / 1000}秒");  //主线程在此处没有进行等待
        }

        /// <summary>
        /// 将打印线程委托给UI线程来执行
        /// </summary>
        /// <param name="text"></param>
        private void AppendLineThread(string text)
        {
            this.Invoke((() => AppendLine(text)));
        }




  public  class Data
    {
        /// <summary>
        /// 书目集合
        /// </summary>
        public readonly static List<Book> Books = new()
        {
            new Book("封神演义", 1),    //时长
            new Book("三国演义", 2),
            new Book("西游记", 1),
            new Book("红楼梦", 1),
            new Book("聊斋志异", 2),
            new Book("玉林外史", 1),
            new Book("朝花夕拾", 1),
            new Book("水浒传", 1),
        };
   }

   public  class Book
    {
        
        public string? Name { get; }
        public int Duration { get; }  //查询测试延时时间
        public Book(string name,int second)
        {
            Name = name;
            Duration= second;
        }
        private  string Result(long milliseconds)
        {
            return $"{Name.PadRight(12,'-')} 用时: {Convert.ToSingle(milliseconds)/1000}秒";
        }
        //检索
       public  string  Search()
        {
            Stopwatch sw = Stopwatch.StartNew();
            //检索逻辑
            Thread.Sleep(Duration * 1000);
            //……
            sw.Stop();
            //制作完成,返回消息
            return Result(sw.ElapsedMilliseconds);
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值