ASP.NET多线程的使用
多線程概述:
? ? ? ? 線程,是操作系統中的術語,是操作系統進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。一個進程可以有很多線程,每條線程并行執行不同的任務。同一進程中的多條線程將共享該進程中的全部系統資源,如虛擬地址空間,文件描述符和信號處理等等。但同一進程中的多個線程有各自的調用棧(call stack),自己的寄存器環境(register context),自己的線程本地存儲(thread-local storage)。我們把用來執行用戶任務的線程稱為工作線程。而線程池,是一種成熟的線程使用模式。
為什么要創建線程池?
線程池屬于對象池.所有對象池都具有一個非常重要的共性,就是為了最大程度復用對象.那么,線程池的最重要的特征也就是最大程度利用線程。所以線程池的目的就是為了減少創建和切換線程的額外開銷,利用已經的線程多次循環執行多個任務從而提高系統的處理能力。
在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點傷害。");}}}} }創建web api項目進行接口測試
創建WebAPI項目,方便測試?
修改【App_Start/WebApiConfig.cs】配置文件
添加取消XML返回配置
//取消XML返回 GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();添加{action}訪問路徑設置
routeTemplate: "api/{controller}/{action}/{id}",添加【API】接口:
依次選擇【Web API】->【Web API 2 控制器 - 空】->【添加】:
輸入文件名【Test】,點擊【添加】
【TestController.cs】編碼:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Threading; using System.Web.Http;namespace webApi.Controllers {public class TestController : ApiController{/// <summary>/// 計時器/// </summary>public static int times = 0;/// <summary>/// 計時器開關/// </summary>public static bool ctrl = false;/// <summary>/// 開啟計時器線程/// </summary>/// <param name="type">0、關閉<br/>1、開啟</param>/// <returns></returns>[HttpGet]public object StartTime(string type){ctrl = type.Equals("0") ? false : Times();return ctrl ? "啟動成功" : "關閉成功";}/// <summary>/// 獲取計時的時間/// </summary>/// <returns></returns>[HttpGet]public object GetTime() {return times;}/// <summary>/// 開啟計時/// </summary>/// <returns></returns>private bool Times() {Thread t = new Thread(()=>{while (ctrl) {Thread.Sleep(1000);//休息1秒times += 1;}});//啟動t.Start();return true;}} }代碼功能測試:
設為啟動項:
?啟動項目:
選擇【API】?
?兩個接口都可以看到:
?訪問方式:
【http://localhost:2298/api/Test/StartTime?type=0】開啟或關閉
?【http://localhost:2298/api/Test/GetTime】獲取時間
開啟測試:
【http://localhost:2298/api/Test/StartTime?type=1】
?稍等一會測試時間:【http://localhost:2298/api/Test/GetTime】
關閉測試:
可以看到試用多線程可以當然控制時間,控制開關操作,那么這類操作基本上都會在各種活動中用到,我之前的老總就喜歡各種各樣的活動,每次我都會做類似的開關。當然,這個東西不僅僅用在這個地方,還有很多的環境都會用到,咱們要做到具體問題具體分析,可以在編碼過程中為大家解決很多問題。
到這里,多線程的講解就結束了,希望能對大家有所幫助,歡迎一鍵三連。
時間判斷我這里有一個【Java】版本的,【C#】的類似。
【判斷當前時間是否在某個時間范圍內_紅目香薰-CSDN博客】
總結
以上是生活随笔為你收集整理的ASP.NET多线程的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#反射使用方法过程及步骤
- 下一篇: socket通信(C#)