zoukankan      html  css  js  c++  java
  • 第二十六章 计算限制的异步操作

    多线程涉及到很多知识和技巧…

    1.线程

    创建线程是有较大的开销的,每个线程都会占用一定的内存Windows为每个线程的用户模式分配1M的内存,分配24K的内科模式栈,虽然线程可能不运行,切换线程也是有代价的,需要切换线程上下文.

    2. CLR线程池

    每个CLR拥有一个线程池.线程池维护线程用来执行用户的异步操作请求.创建一个线程并使用结束之后,线程不会立即销毁,而是返回线程池,等待下一次调用,如果长时间没有用才会自己销毁.类似资源池.两个任务可能使用的是一个线程.

    3. 执行上下文

    每个线程都关联了一个执行上下文数据,线程执行代码时,有些操作会受到线程的执行上下文的设置的影响.

    默认情况下,初始线程的执行上下文会流向辅助线程,但是会造成一定的性能影响.

    ExecutionContext类允许控制线程的执行上下文如何流向另一个线程.

    4. 协作式取消

    如果需要长时间运行的计算限制操作需要运行的过程中取消,可以创建一个CancellationTokenSource通知 System.Threading.CancellationToken,告知其应被取消.将CancellationTokenSource.Token传递到开辟的线程中,在新线程中检测token.lsCancelationResuested属性,如果在主线程中调用了Cancel方法,新线程就可以检测到lsCancelationResuested属性的变化.

        var cts = new CancellationTokenSource();

        ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));

        Thread.Sleep(1000);
        Console.WriteLine("Press ENTER to stop");
        Console.ReadLine();
        cts.Cancel();
        Console.ReadLine();
    }

    private static void Count(CancellationToken token, int countTo)
    {
        for (int i = 0; i < countTo; i++) {
            if (token.IsCancellationRequested) {
                Console.WriteLine("token.IsCancellationRequested Called");
                break;
            }
            Console.WriteLine(i);
            Thread.Sleep(200);
        }
    }

    cts.Token.Register 注册一个将在取消此 System.Threading.CancellationToken 时调用的委托

    5. 任务Task

    ThreadPool.QueueUserWorkItem创建一个异步的受计算限制的的操作是非常简单的,但是不知道操作什么时候完成.Task可以实现这样的效果.

    task.Wait()方法,等待 System.Threading.Tasks.Task 完成执行过程.Result获取方法的返回值.

    Task当然也可以使用CancellationTokenSource进行操作的取消.

    Result 如果任务还没有结束,就调用Result获取结果,在内部会调用Wait方法,导致线程阻塞.

    task.ContinueWith 创建一个在目标 System.Threading.Tasks.Task 完成时执行的延续任务.

    TaskContinuationOptions  为通过使用 System.Threading.Tasks.Task.ContinueWith方法创建的任务指定行为.可以指定什么情况下才执行Continue线程.

    子线程还可以创建子线程并设置TaskContinuationOptions  为AttachedToParent,那么新的子线程也会作为子线程的一部分,”算是同级了”.

    如果希望多个Task共享一些设置和传入的参数可以创建TaskFactory或TaskFactory<>.由TaskFactory创建的Task都共享这些设置.

    6. Parallel的静态For,ForEach和Invoke方法

    如果循环当中的操作可以并行,而且没有修改共享数据,可以使用Parallel的这几个方法,这些方法内部会调用线程参与处理.

    7. 并行语言集成查询(PLINQ)

    System.Linq.ParallelEnumerable类实现了这些功能.

    一般的Linq查询是一个线程顺序处理查询数据,为了提高性能可以使用并行Linq,将集合中的数据项的处理分散到多个CPU上,以便并发处理多个数据项.当然,这里有线程同步的性能影响.

    8.线程注意事项

    System.Timers.Timer是System.Threading.Timer的包装类.与设计平面相关的时候可以使用,别的情况下,尽量不要使用.

    尽量不要手工设置线程池的最大线程数.

  • 相关阅读:
    eclipse插件开发:创建向导和导航器配置
    eclipse插件开发:属性视图
    标识出下列SQL语句的执行先后顺序
    webapi和webservice的本质区别
    某仪表上市公司.net-————Sql面试题
    Asp.net MVC 用EF来保存高精度小数时会碰到保留4位小数时,后两位默认为0的解决方法
    Asp.net MVC 集成AD域认证
    jquery zTree插件 json 数据详解
    模板列传值到子窗体中,子窗体中多选gridview中checkbox保存数据多项到数据库中
    asp.net comp雷达图
  • 原文地址:https://www.cnblogs.com/zhangliming/p/3508595.html
Copyright © 2011-2022 走看看