用Thread和Task实现WinFrom里面的进度条

新建WinFrom项目,在界面上添加两个按钮
分别用Thread和Task实现进度条效果

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //普通Thread实现进度条
        private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine("主线程开始");

            new Thread(DoProcessing).Start(); //没有使用线程池,每次调用都开启新线程
            //ThreadPool.QueueUserWorkItem(DoProcessing);//使用线程池,重复开启的时候回去线程池拿空闲的线程

            Console.WriteLine("主线程结束");
        }

        //在方法上加上 async 
        private async void button2_Click(object sender, EventArgs e)
        {
            await UpdateUi2();

            //async.await的语法糖为我们带来了更好的异步编程体验
        }


        #region Thread

        void UpdateUi(int percent)
        {
            //UI操作
            button1.Text = string.Format("{0}%", percent);
        }

        void DoProcessing(object obj)
        {
            for (int i = 0; i <= 5; ++i)
            {
                Thread.Sleep(500);
                Console.WriteLine("---------- " + i);
                Action<int> updateUi = new Action<int>(UpdateUi);
                this.Invoke(updateUi, i);
            }
        }

        #endregion


        #region task,async,await

        private static int _percent = 0;

        int DoProcessing2()
        {
            Console.WriteLine("Thread id in DoProcessing: {0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(500);
            return ++_percent;
        }

        async Task UpdateUi2()
        {
            _percent = 0;
            button1.Text = string.Format("{0}%", 0);
            while (_percent < 5)
            {
                //await起到释放主线程的作用
                int percent = await Task.Run(() => DoProcessing2());
                //在子线程处理完成后,又请求主线程继续下面的代码,下面的代码相当于Thread的回调
                button2.Text = string.Format("{0}%", percent);
            }
        }

        #endregion


        #region 参考

        private void button3_Click(object sender, EventArgs e)
        {
            Thread.Sleep(3000); //堵塞主线程
            button1.Text = string.Format("99%");
        }

        #endregion
    }
}

C# 同步方法改异步方法

先举例一个同步方法 Greeting 开始,该方法等待一段时间后,返回一个字符串:

static string Greeting(string name)
{
  TraceThreadAndTask($"running {nameof(Greeting)}"); 
  Task.Delay(3000).Wait(); 
  return $"Hello, {name}";
}

同步改异步

定义方法 GreetingAsync,可以使方法异步化。基于任务的异步模式指定,在异步方法名后加上 Async 后缀,并返回一个任务。异步方法 GreetingAsync 和同步方法 Greeting 具有相同的输入参数,但是它返回的是 Task。Task 定义了一个返回字符串的任务。一个比较简单的做法是用 Task.Run 方法返回一个任务。泛型版本的 Task.Run() 创建一个返回字符串的任务。由于编译器已经知道实现的返回类型(Greeting返回字符串),因此还可以使用 Task.Run() 来简化实现代码:

static Task<string> GreetingAsync(string name) =>
  Task.Run<string> (() =>
  {
    TraceThreadAndTask($"running {nameof(GreetingAsync)}");
    return Greeting(name);
  });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值