zoukankan      html  css  js  c++  java
  • .NET : 多线程面面观

    在.NET程序中,你需要了解多线程的知识包括如下几点

    1. 什么是多线程

    线程是目前程序可以直接控制的一个单元。我们的程序是运行在下面这样的一个环境中的

    操作系统==>进程(Process)==>应用程序域(AppDomain)

    通常情况下,一个.NET程序集(尤其是exe),默认还是有一个独立的进程。然后在这个进程中,会至少有一个应用程序域(AppDomain),这种新的机制是可以更好地提供程序集的安全性。

    我们的代码需要在所谓的线程上运行。而一个程序至少会有一个线程。

    如果我们需要,我们当然可以出创建多个线程。

    2. 为什么要多线程

    多线程,主要是因为我们想提高程序的可伸缩性。例如,我们有很多任务需要并行进行,那么我们可能需要多线程。

    3. 怎么理解多线程

    通常,我喜欢比较所谓的同步和异步。同步(所有任务在单个线程中依次排队执行),相当于单车道。而异步,则相当于多车道。从这个意义上讲,多车道当然提高了车辆通行的流量。当然,也正因为如此,多线程并不是免费的午餐。它肯定有成本,因为多个车道之间转换和同步是相对来说比较复杂的。

    4. 线程是不是越多越好

    不是!多线程虽然看起来是多车道,但其实那是我们一个比较形象的比喻而已。除非你真的拥有多个CPU,那么多线程实际上是一个假象,就是说,因为CPU的时间总是有限的,那么CPU需要频繁地切换,在某个时间执行某个线程的任务。这种情况,如果用的不好,反而增加了CPU的负担,降低了系统性能。

    而且,多线程操作需要你有更好的专业知识,包括线程之间的安全性,同步,切换等等。

    5. 三种操作多线程的方法

    • 直接创建Thread对象,并且调用它的Start方法(更有操控力)
    • 使用ThreadPool.QueueUserWorkItem方法(更有安全性)
    • 使用.NET 2.0提供的BackgroundWorker(更方便)

    下面来看一个例子

    例如,我们有下面这样一个方法,需要单独开一个线程去工作

    static void SomeMethod(object max)
    {
        int length = (int)max;
        for (int i = 0; i < length; i++)
        {
            Console.WriteLine(i.ToString());
        }
    }

    这个方法很简单,根据一个传入的参数,做一个循环

     

    下面来看,如何使用上面三种方法实现多线程

    直接使用Thread对象

    Thread thread = new Thread(new ParameterizedThreadStart(SomeMethod));
    thread.Start(100);

    使用ThreadPool对象

    ThreadPool.QueueUserWorkItem(new WaitCallback(SomeMethod), 100);

    使用BackgroundWorker

    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.RunWorkerAsync();

    static void worker_DoWork(object sender, DoWorkEventArgs e)
    {
         SomeMethod(100);
    }

    本文完整代码如下:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;

    using System.ComponentModel;

    namespace ConsoleApplication1
    {
        /// <summary>
        /// 多线程的范例
        /// 作者:陈希章
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                //使用Thread对象
                Thread thread = new Thread(new ParameterizedThreadStart(SomeMethod));
                thread.Start(100);
                //使用ThreadPool对象
                ThreadPool.QueueUserWorkItem(new WaitCallback(SomeMethod), 100);
                //使用BackgroundWorker对象

                BackgroundWorker worker = new BackgroundWorker();
                worker.DoWork += new DoWorkEventHandler(worker_DoWork);
                worker.RunWorkerAsync();
                Console.Read();
            }

            static void worker_DoWork(object sender, DoWorkEventArgs e)
            {
                SomeMethod(100);
            }

            static void SomeMethod(object max)
            {
                int length = (int)max;
                for (int i = 0; i < length; i++)
                {
                    Console.WriteLine(i.ToString());
                }
            }
        }
    }

    本文由作者:陈希章 于 2009/6/30 8:35:47 发布在:http://www.cnblogs.com/chenxizhang/
    本文版权归作者所有,可以转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    更多博客文章,以及作者对于博客引用方面的完整声明以及合作方面的政策,请参考以下站点:陈希章的博客中心
  • 相关阅读:
    IIS7.5 webapi 不支持 Delete、Put 解决方法
    pip 安装 MySQL-python 失败
    Windows 下针对python脚本做一个简单的进程保护
    Python 多线程 Condition 的使用
    Python 无限循环
    Window nginx+tomcat+https部署方案 支持ios9
    Window Redis分布式部署方案 java
    Struts2注解 特别注意
    PermGen space Eclipse 终极解决方案
    特别备注一下一个缓存加载的问题,百度上还搜不出来,在一个老外的网站上看到的
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1513639.html
Copyright © 2011-2022 走看看