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

async和await语法糖

通过下面的代码体会一下async和await语法糖带来的效果, 打印顺序是1,2,3

private void button1_Click(object sender, EventArgs e)
{
    AsyncTest();//异步
    Console.WriteLine("打印2"); //当执行到Async方法的await后, 启用子线程, 马上跳出Async方法继续执行后续的代码
    Console.ReadLine();
}

//用async和await包装出来的线程
private async void AsyncTest()
{
    Console.WriteLine("打印1");
    await Task.Run(() => Thread.Sleep(5 * 1000));//到达await后执行子线程, 马上跳出Async方法继续执行后续的代码
    Console.WriteLine("打印3");
    textBox1.Text = "await完成后回到主线程执行后续代码! 相当于子线程的回调";
}

WinForm上的进度条实现

新建WinForm项目,在界面上添加两个按钮
分别用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
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是详细配置及案例demo: 1. 安装aws-sdk和aws-sdk-vue ``` npm install aws-sdk aws-sdk-vue --save ``` 2. 创建一个S3的Vue组件 ```vue <template> <div> <input type="file" @change="onFileChange"/> <div v-if="isUploading"> <div>Uploading...{{uploaded}}%</div> <progress :value="uploaded" max="100"></progress> </div> </div> </template> <script> import AWS from 'aws-sdk'; import { AWSS3Vue } from 'aws-sdk-vue'; export default { name: 'S3Uploader', data() { return { isUploading: false, uploaded: 0, file: null, s3: null, uploadId: null, parts: [] }; }, computed: { region() { return 'your-s3-region'; }, bucketName() { return 'your-s3-bucket-name'; }, accessKeyId() { return 'your-access-key-id'; }, secretAccessKey() { return 'your-secret-access-key'; }, maxPartSize() { return 5 * 1024 * 1024; // 5MB }, partSize() { return Math.max(Math.ceil(this.file.size / 10000), this.maxPartSize); }, numParts() { return Math.ceil(this.file.size / this.partSize); } }, methods: { async onFileChange(event) { this.file = event.target.files[0]; this.s3 = AWSS3Vue({ accessKeyId: this.accessKeyId, secretAccessKey: this.secretAccessKey, region: this.region }); this.uploadId = await this.createMultipartUpload(); await this.uploadParts(); await this.completeMultipartUpload(); }, async createMultipartUpload() { const response = await this.s3.createMultipartUpload({ Bucket: this.bucketName, Key: this.file.name, }).promise(); return response.UploadId; }, async uploadParts() { for (let i = 0; i < this.numParts; i++) { const start = i * this.partSize; const end = Math.min(start + this.partSize, this.file.size); const buffer = this.file.slice(start, end); const response = await this.s3.uploadPart({ Bucket: this.bucketName, Key: this.file.name, PartNumber: i + 1, UploadId: this.uploadId, Body: buffer }).promise(); this.parts.push({ ETag: response.ETag, PartNumber: i + 1 }); this.uploaded = Math.ceil((i + 1) / this.numParts * 100); } }, async completeMultipartUpload() { await this.s3.completeMultipartUpload({ Bucket: this.bucketName, Key: this.file.name, UploadId: this.uploadId, MultipartUpload: { Parts: this.parts } }).promise(); } } }; </script> ``` 3. 在Vue应用中使用S3Uploader组件 ```vue <template> <div> <s3-uploader /> </div> </template> <script> import S3Uploader from '@/components/S3Uploader.vue'; export default { name: 'App', components: { S3Uploader } }; </script> ``` 在上面的示例中,我们使用AWS SDK和aws-sdk-vue实现了一个基本的S3上传器,它可以将大文件分成多个部分并上传到S3存储桶。我们还使用了计算属性来计算分块大小和分块数量,并使用async/await实现了异步上传。 最后,我们使用Vue组件来封装整个上传过程,并使用Vue组件的事件来处理上传成功或失败的情况。同时,我们还添加了一个简单的进度条来显示上传进度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值