.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/
本文版权归作者所有,可以转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多博客文章,以及作者对于博客引用方面的完整声明以及合作方面的政策,请参考以下站点:陈希章的博客中心
posted @ 2009-06-30 08:36  陈希章  阅读(458)  评论(0编辑  收藏  举报