为什么要创建线程池?
线程池属于对象池.所有对象池都具有一个非常重要的共性,就是为了最大程度复用对象.那么,线程池的最重要的特征也就是最大程度利用线程。所以线程池的目的就是为了减少创建和切换线程的额外开销,利用已经的线程多次循环执行多个任务从而提高系统的处理能力。
在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(创建控制台项目):
测试编码:
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点伤害。");
}
当输入过快的时候无法被循环监听到:
一同运行,相当于两个线程会交替的进行执行。故而会出现如上现象。所以咱们开启线程的时候
演示代码
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);
}
执行效果:
以上效果可以说明,两个线程是相互交替执行,并非共同执行。
所以说,如果进行同时监听,无法正确进行线程操作。
通过如下方法即可进行线程交互:
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);
}
可以看到,两个线程基本上都是在交互执行:
多次执行总会找到无法交互的地方。
说明线程休息的时间简短,线程1并没有争抢线程成功。可以加大线程休息时间。 Thread.Sleep(5);//每次线程休息5毫秒 重新测试,多次执行,出现争抢失败的情况就很少了:
重新测试监听
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点伤害。");
多线程或者异步调用中如何访问HttpContext?
前面我还提到在APM模式下的异步完成回调时,访问HttpContext.Current也会返回null,那么此时该怎么办呢?
答案有二种:1. 在类型中添加一个字段来保存HttpContext的引用(异步开始前)。
基于Asp.Net Mvc开发的个人博客系统
一个基于Mvc 5构建的简单、代码层级分明的开源个人博客系统。前端美观大气、后台采用RightControl .NET通用角色权限系统,开发简单、效率高。网站配置采用XML配置,灵活可以根据自己是需求进行个性化配置。系统功能完备,完全可以满足需求,基本不用二次开发,非常使用程序员的个人博客。
ASP.NET Core MVC+Layui使用EF Core连接MySQL执行简单的CRUD操作
ASP.NET Core MVC+Layui使用EF Core连接MySQL执行简单的CRUD操作