ASP.NET多线程的使用(一)

简介: 线程,是操作系统中的术语,是操作系统进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以有很多线程,每条线程并行执行不同的任务。同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。我们把用来执行用户任务的线程称为工作线程。而线程池,是一种成熟的线程使用模式。

30.png为什么要创建线程池?

 线程池属于对象池.所有对象池都具有一个非常重要的共性,就是为了最大程度复用对象.那么,线程池的最重要的特征也就是最大程度利用线程。所以线程池的目的就是为了减少创建和切换线程的额外开销,利用已经的线程多次循环执行多个任务从而提高系统的处理能力。


 在ASP.NET工作进程中有两种线程池,Worker线程池处理所有传入的请求, I / O线程池处理的I / O(访问文件系统,Web服务和数据库等)。每个应用程序域都有其自己的线程池,可以排队到线程池的操作的数量只受可用内存的限制,然而,对线程池中的线程数的限制在这个过程中可以同时被激活。


       当我们发出一个(异步)页面请求。一个Worker线程就会被从Worker线程池中取出, 这个Worker线程会触发I/O操作。当I/O操作开始时,另一个线程将会被从I/O线程池中取出,在收到I/O线程的返回值之前,Worker线程会一直处于闲置状态。所以,如果你的页面加载事件触发了多个I/O操作,那么,Worker线程就很可能会被闲置很长时间。而线程池能够把正处于闲置状态的Worker线程回收,使他能够为其他的页面请求提供服务。从而,降低系统开销。



演示demo(创建控制台项目):

31.png



测试编码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace duo_0926
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => {
                Console.WriteLine("启动吃药的监听:输入1代表吃药");
                Ation1();
            });
            t1.Start();
            Thread t2 = new Thread(() => {
                Console.WriteLine("启动攻击的监听:输入2代表攻击");
                Ation2();
            });
            t2.Start();
        }
        /// <summary>
        /// 吃药的监听
        /// </summary>
        public static void Ation1() {
            while (true)
            {
                string ctrl = Console.ReadLine();
                if (ctrl.Equals("1")) {
                    Console.WriteLine("吃药,血量增加200点。");
                }
            }
        }
        /// <summary>
        /// 攻击的监听
        /// </summary>
        public static void Ation2()
        {
            while (true)
            {
                string ctrl = Console.ReadLine();
                if (ctrl.Equals("2"))
                {
                    Console.WriteLine("攻击,对敌方造成200点伤害。");
                }
            }
        }
    }
}

当输入过快的时候无法被循环监听到:

32.png

一同运行,相当于两个线程会交替的进行执行。故而会出现如上现象。所以咱们开启线程的时候

演示代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace duo_0926
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => {
                Ation1();
            });
            t1.Start();
            Thread t2 = new Thread(() => {
                Ation2();
            });
            t2.Start();
        }
        /// <summary>
        /// 线程1
        /// </summary>
        public static void Ation1() {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine("线程1:"+i);
            }
        }
        /// <summary>
        /// 线程2
        /// </summary>
        public static void Ation2()
        {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine("线程2:" + i);
            }
        }
    }
}

执行效果:

33.png

以上效果可以说明,两个线程是相互交替执行,并非共同执行。


所以说,如果进行同时监听,无法正确进行线程操作。


通过如下方法即可进行线程交互:


Thread.Sleep(1);//休息1毫秒,不争抢线程

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace duo_0926
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => {
                Ation1();
            });
            t1.Start();
            Thread t2 = new Thread(() => {
                Ation2();
            });
            t2.Start();
        }
        /// <summary>
        /// 线程1
        /// </summary>
        public static void Ation1() {
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(1);
                Console.WriteLine("线程1:"+i);
            }
        }
        /// <summary>
        /// 线程2
        /// </summary>
        public static void Ation2()
        {
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(1);
                Console.WriteLine("线程2:" + i);
            }
        }
    }
}

可以看到,两个线程基本上都是在交互执行:

34.png

多次执行总会找到无法交互的地方。

35.png

说明线程休息的时间简短,线程1并没有争抢线程成功。可以加大线程休息时间。 Thread.Sleep(5);//每次线程休息5毫秒 重新测试,多次执行,出现争抢失败的情况就很少了:  

36.png

重新测试监听

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace duo_0926
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => {
                Console.WriteLine("启动吃药的监听:输入1代表吃药");
                Ation1();
            });
            t1.Start();
            Thread t2 = new Thread(() => {
                Console.WriteLine("启动攻击的监听:输入2代表攻击");
                Ation2();
            });
            t2.Start();
        }
        /// <summary>
        /// 吃药的监听
        /// </summary>
        public static void Ation1()
        {
            while (true)
            {
                Thread.Sleep(1);
                string ctrl = Console.ReadLine();
                if (ctrl.Equals("1"))
                {
                    Console.WriteLine("吃药,血量增加200点。");
                }
            }
        }
        /// <summary>
        /// 攻击的监听
        /// </summary>
        public static void Ation2()
        {
            while (true)
            {
                Thread.Sleep(1);
                string ctrl = Console.ReadLine();
                if (ctrl.Equals("2"))
                {
                    Console.WriteLine("攻击,对敌方造成200点伤害。");
                }
            }
        }
    }
}

37.png


相关文章
|
7月前
|
并行计算 安全 Java
C# .NET面试系列四:多线程
<h2>多线程 #### 1. 根据线程安全的相关知识,分析以下代码,当调用 test 方法时 i > 10 时是否会引起死锁? 并简要说明理由。 ```c# public void test(int i) { lock(this) { if (i > 10) { i--; test(i); } } } ``` 在给定的代码中,不会发生死锁。死锁通常是由于两个或多个线程互相等待对方释放锁而无法继续执行的情况。在这个代码中,只有一个线程持有锁,且没有其他线程参与,因此不
425 3
|
1月前
|
开发框架 Java .NET
.net core 非阻塞的异步编程 及 线程调度过程
【11月更文挑战第12天】本文介绍了.NET Core中的非阻塞异步编程,包括其基本概念、实现方式及应用示例。通过`async`和`await`关键字,程序可在等待I/O操作时保持线程不被阻塞,提高性能。文章还详细说明了异步方法的基础示例、线程调度过程、延续任务机制、同步上下文的作用以及如何使用`Task.WhenAll`和`Task.WhenAny`处理多个异步任务的并发执行。
|
6月前
|
开发框架 监控 Java
【.NET Core】多线程之线程池(ThreadPool)详解(二)
【.NET Core】多线程之线程池(ThreadPool)详解(二)
105 3
|
6月前
|
SQL 开发框架 Java
【.NET Core】多线程之线程池(ThreadPool)详解(一)
【.NET Core】多线程之线程池(ThreadPool)详解(一)
444 2
|
6月前
|
算法 安全 Java
【.NET Core】 多线程之(Thread)详解
【.NET Core】 多线程之(Thread)详解
82 1
|
数据采集 Java C++
【.NET 6】多线程的几种打开方式和代码演示
多线程无处不在,平常的开发过程中,应该算是最常用的基础技术之一了。以下通过Thread、ThreadPool、再到Task、Parallel、线程锁、线程取消等方面,一步步进行演示多线程的一些基础操作。欢迎大家围观。如果大佬们有其他关于多线程的拓展,也欢迎在评论区进行留言,大佬们的知识互助,是.net生态发展的重要一环,欢迎大佬们进行留言,帮助更多的人。
282 0
【.NET 6】多线程的几种打开方式和代码演示
|
安全 NoSQL MongoDB
.Net线程同步技术解读
C#开发者(面试者)都会遇到lock(Monitor),Mutex,Semaphore,SemaphoreSlim这四个与锁相关的C#类型,本文期望以最简洁明了的方式阐述四种对象的区别。
.Net线程同步技术解读
|
XML 存储 开发框架
ASP.NET多线程的使用(二)
线程,是操作系统中的术语,是操作系统进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以有很多线程,每条线程并行执行不同的任务。同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。我们把用来执行用户任务的线程称为工作线程。而线程池,是一种成熟的线程使用模式。
198 0
ASP.NET多线程的使用(二)
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
48 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
79 0