码迷,mamicode.com
首页 > 编程语言 > 详细

c# 多线程

时间:2019-03-22 11:44:16      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:htm   开启   时间   html   mic   show   exception   cpu   ++   

学历代表你的过去,能力代表你的现在,学习代表你的将来

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

今儿转发一篇关于C#多线程的大作,转发自:https://www.cnblogs.com/wyt007/p/9486752.html

1、线程基础

1.1、创建线程

技术图片
static void Main(string[] args)
{
    Thread t = new Thread(PrintNumbers);
    t.Start();//线程开始执行
    PrintNumbers();
    Console.ReadKey();
}

static void PrintNumbers()
{
    Console.WriteLine("Starting...");
    for (int i = 1; i < 10; i++)
    {
        Console.WriteLine(i);
    }
}
View Code

尝试运行上述程序,执行结果如下:

技术图片技术图片

从执行的结果图中,我们发现执行的结果每次可能会不一样,究其原因,是因为进程被开启并执行的模式采用的是异步的方式!

划重点,要考:(线程/进程的执行模式是异步的)

 1.2、暂停线程

技术图片
class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(PrintNumbersWithDelay);
        t.Start();
        PrintNumbers();
        Console.ReadKey();
    }

    static void PrintNumbers()
    {
        Console.WriteLine("Starting...");
        for (int i = 1; i < 10; i++)
        {
            Console.WriteLine(i);
        }
    }

    static void PrintNumbersWithDelay()
    {
        Console.WriteLine("Starting...");
        for (int i = 1; i < 10; i++)
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));//暂停2S
            Console.WriteLine(i);
        }
    }
}
View Code

执行结果图:

技术图片

上图中标红处是每隔两秒钟打印出来的,根据图中的两个Starting...出现的位置,我们可以得到1.1处的结论:线程/进程是异步执行的。在后文中将不再重复!

工作原理

  当程序运行时,会创建一个线程,该线程会执行PrintNumbersWithDelay方法中的代码。然后会立即执行PrintNumbers方法。关键之处在于在PrintNumbersWithDelay方法中加入了Thread.Sleep方法调用。这将导致线程执行该代码时,在打印任何数字之前会等待指定的时间(本例中是2秒钟),当线程处于休眠状态时,它会占用尽可能少的CPU时间。结果我们4·会发现通常后运行的PrintNumbers方法中的代码会比独立线程中的PrintNumbersWithDelay方法中的代码先执行。

划重点,要考:Sleep()方法,用于睡眠/暂停线程。

1.3、线程等待

技术图片
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Starting program...");
        Thread t = new Thread(PrintNumbersWithDelay);
        t.Start();
        t.Join();
        Console.WriteLine("Thread completed");
    }

    static void PrintNumbersWithDelay()
    {
        Console.WriteLine("Starting...");
        for (int i = 1; i < 10; i++)
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine(i);
        }
    }
}
View Code

工作原理

  当程序运行时,启动了一个耗时较长的线程来打印数字,打印每个数字前要等待两秒。但我们在主程序中调用了t.Join方法,该方法允许我们等待直到线程t完成。当线程t完成 "时,主程序会继续运行。借助该技术可以实现在两个线程间同步执行步骤。第一个线程会等待另一个线程完成后再继续执行。第一个线程等待时是处于阻塞状态(正如暂停线程中调用 Thread.Sleep方法一样),

执行结果图如下:

技术图片

工作原理

  当程序运行时,启动了一个耗时较长的线程来打印数字,打印每个数字前要等待两秒。但我们在主程序中调用了t.Join方法,该方法允许我们等待直到线程t完成。当线程t完成 "时,主程序会继续运行。借助该技术可以实现在两个线程间同步执行步骤。第一个线程会等待另一个线程完成后再继续执行。第一个线程等待时是处于阻塞状态(正如暂停线程中调用 Thread.Sleep方法一样),

上述我们知道线程是异步执行的,主线程无需等待子线程的返回结果(执行完),如果我们将上述方法的 t.Join方法去掉,执行结果如下图:

技术图片

主线程无需等待子线程的执行结果。

划重点,要考:Join()方法用来阻塞主进程,主进程必须等待子进程执行完成后才会往下执行!利用Join方法,可实现两个线程/进程同步执行的问题!

1.4、终止进程

技术图片
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Starting program...");
        Thread t = new Thread(PrintNumbersWithDelay);
        t.Start();
        Thread.Sleep(TimeSpan.FromSeconds(6));
        t.Abort();
        Console.WriteLine("A thread has been aborted");
    }

    static void PrintNumbersWithDelay()
    {
        Console.WriteLine("Starting...");
        for (int i = 1; i < 10; i++)
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine(i);
        }
    }
}
View Code

工作原理

  当主程序和单独的数字打印线程运行时,我们等待6秒后对线程调用了t.Abort方法。这给线程注入了ThreadAbortException方法,导致线程被终结。这非常危险,因为该异常可以在任何时刻发生并可能彻底摧毁应用程序。另外,使用该技术也不一定总能终止线程。目-标线程可以通过处理该异常并调用Thread.ResetAbort方法来拒绝被终止。因此并不推荐使用,Abort方法来关闭线程。可优先使用一些其他方法,比如提供一个CancellationToken方法来,取消线程的执行。

执行结果:

技术图片

划重点,要考:Abort()方法用来终止线程的执行

1.5、监测线程状态

技术图片
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Starting program...");
        Thread t = new Thread(PrintNumbersWithStatus);
        Thread t2 = new Thread(DoNothing);
        Console.WriteLine(t.ThreadState.ToString());
        t2.Start();
        t.Start();
        for (int i = 1; i < 30; i++)
        {
            Console.WriteLine(t.ThreadState.ToString());
        }
        Thread.Sleep(TimeSpan.FromSeconds(6));
        t.Abort();
        Console.WriteLine("A thread has been aborted");
        Console.WriteLine(t.ThreadState.ToString());
        Console.WriteLine(t2.ThreadState.ToString());

        Console.ReadKey();
    }

    static void DoNothing()
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
    }

    static void PrintNumbersWithStatus()
    {
        Console.WriteLine("Starting...");
        Console.WriteLine(Thread.CurrentThread.ThreadState.ToString());
        for (int i = 1; i < 10; i++)
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine(i);
        }
    }
}
View Code

工作原理

  当主程序启动时定义了两个不同的线程。一个将被终止,另一个则会成功完成运行。线,.程状态位于Thread对象的ThreadState属性中。ThreadState属性是一个C#枚举对象。刚开始线程状态为ThreadState.Unstarted,然后我们启动线程,并估计在一个周期为30次迭代的,区间中,线程状态会从ThreadState.Running变为ThreadState. WaitSleepJoin。

划重点,要考:ThreadState是线程的一个属性,是一个枚举类型,不同的枚举值代表线程不同的状态!

请注意始终可以通过Thread.CurrentThread静态属性获得当前Thread对象。

  如果实际情况与以上不符,请增加迭代次数。终止第一个线程后,会看到现在该线程状态为ThreadState.Aborted,程序也有可能会打印出ThreadState.AbortRequested状态。这充分说明了同步两个线程的复杂性。请记住不要在程序中使用线程终止。我在这里使用它只是为 ,了展示相应的线程状态。

  最后可以看到第二个线程t2成功完成并且状态为ThreadState.Stopped。另外还有一些其,他的线程状态,但是要么已经被弃用,要么没有我们实验过的几种状态有用。

1.6、

c# 多线程

标签:htm   开启   时间   html   mic   show   exception   cpu   ++   

原文地址:https://www.cnblogs.com/chenwolong/p/10577198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!