• Task CancellationTokenSource和Task.WhenAll的应用


    Task是.net4.0推出的异步编程类,与ThreadPool.QueneUserWorkItem方法类似的是,Task也是使用线程池来工作的.但Task比起这个QueneUserWorkItem的优势是它的可控制性,能够通过CancellationTokenSource控制Task运行任务的取消,还能够知道Task运行任务是何时完成的.Task对线程的阻塞控制有静态方法WaitAll(params Task[] tasks)我的理解是,当所有的tasks都完成得时候线程就不会阻塞,WaitAny(params Task[] tasks))表示只要tasks中其中任意一个任务完成,线程就不会再是阻塞状态.,成员方法Wait方法有四个重载,它们分别是:

    • public void Wait()
    • public bool Wait(TimeSpan timeout)
    • public void Wait(CancellationToken cancellationToken)
    • public bool Wait(int millisecondsTimeout)
    • public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)

    对于Task的介绍就到这里,下面来看看它的一个例子,这个例子,我要做的就是:当点击按钮时,用两个任务t2,t3来sleep5秒钟,同时用任务t1在uI界面死循环的更新listbox读秒时间,当t2,t3任务结束了,在利用Task.WenAll和CancellationTokenSource break掉t1的死循环。效果如图所示:

    代码如下:

    CancellationTokenSource cts = new CancellationTokenSource();
    
            private void button1_Click(object sender, EventArgs e)
            {
    
                Task t2 = new Task(() =>
                {
                    Thread.Sleep(5000);
                });
                //為了说明Task的异步,t2 和 t3都sleep5秒,但程序只数了5秒就结束了,这间接说明t2和t3是异步的
                Task t3 = new Task(() =>
                {
                    Thread.Sleep(5000);
                });
                //死循环读秒
                Task t1 = new Task((obj) =>
                {
    
                    object[] objs = obj as object[];
    
                    CancellationTokenSource cancellationToken = objs[0] as CancellationTokenSource;//这个控制任务取消的
    
                    string strParam = objs[1].ToString();
    
                    int i = 1;
                    while (true)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            break;
                        }
    
                        if (listBox1.InvokeRequired)
                        {
    
                            listBox1.Invoke(new Action(() =>
                            {
                                listBox1.Items.Add(strParam + ":" + i++);
    
                            }));
                        }
                        else
                        {
                            listBox1.Items.Add(strParam + ":" + i++);
                        }
    
                        Delay(1000);
    
                    }
                }, new object[2] { cts, "params" }, cts.Token);//这里随便写了一个参数,当任务需要参数的时候就“{ cts, "params" }“这样传,并且把控制任务取消的令牌cts.Token传进去
    if (button1.Text == "start") 
    { button1.Text
    = "sleep...";
    t1.Start(); t2.Start();
    t3.Start();
    Task task
    = Task.WhenAll(t2, t3);//这个WhenAll不会像WaitAll那样阻塞线程,所以会在t2和t3都sleep的情况下执行t1那个死循环线程
              //这里在建一个死循环任务去判断task是否完成 Task.Run(()
    => { while (true) { if (task.IsCompleted)//当t2和t3都完成得时候,这里就为true { cts.Cancel();//这里是对Task的取消操作,当执行了这句话时,这里cancellationToken.IsCancellationRequested就变成true
    MessageBox.Show("結束!"); break; } } }); } }

    大概就是这样,Task.WenAll是异步的是不会阻塞线程的。

  • 相关阅读:
    python处理url中的中文编码,以及其他编码问题
    深度学习与神经网络
    Windows下为64位的python3.4.3安装numpy
    TOP 10开源的推荐系统简介
    遗传算法
    java调用c++生成的动态和静态库时遇到的问题
    java程序(一)----HashMap同时获取键值
    Deep Learning In NLP 神经网络与词向量
    word2vec使用说明
    Spring入门_02_属性注入
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/10287480.html
Copyright © 2020-2023  润新知