日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#多线程之旅(3)——线程池

發布時間:2023/12/10 C# 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#多线程之旅(3)——线程池 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀目錄

  • 代碼下載
  • 一、介紹
  • 二、通過TPL進入線程池
  • 三、不用TPL進入到線程池

v博客前言

先交代下背景,寫《C#多線程之旅》這個系列文章主要是因為以下幾個原因:1.多線程在C/S和B/S架構中用得是非常多的;2.而且多線程的使用是非常復雜的,如果沒有用好,容易造成很多問題。

v寫在前面

多線程,有利也有弊,使用需謹慎。

v正文開始

代碼下載

Thread_博客園_cnblogs_jackson0714.zip

第一篇~第三篇的代碼示例:

源碼地址:https://github.com/Jackson0714/Threads

回到頂部

一、介紹

無論你什么時候開始一個線程,幾百毫秒會花在整理一個新的local variable stack。每一個線程默認會消耗1MB的內存。線程池通過分享和回收線程來削減這些開銷,允許多線程被應用在一個非常顆粒級的級別而沒有性能損失。當充分利用多核系統去執行密集型計算的并行代碼時這是非常有用的。

線程池也會在線程的總數量上保持一個限制,從而使線程能夠更平穩地運行。太多的線程將會造成管理負擔和使CPU緩存是小,從而造成操作系統不能運行。一旦一個限制到達,job排隊等待直到另外一個完成才開始。這會使任意的并行應用程序成為可能,比如一個web server(同步方法是高級技巧,可以更高效地使用線程池中的線程)。

下面是幾種方式進入線程池:

  • 通過Task Parallel Library(.NET 4.0)
  • 通過調用ThreadPool.QueueUserWorkItem
  • 通過asynchronous delegates
  • 通過BackgroundWorkder
  • 下面的結構直接使用線程池:

  • WCF,Remoting,ASP.NET,ASMX Web Services application servers
  • System.Timers.Timer and System.Threading.Timer
  • Framework methods?由Async結束,比如WebClient(the event-based asynchronous pattern)和大部分的BeginXXX方法(the asynchronous programming model pattern)
  • PLINQ
  • Task Parallel Library(TPL)和PLINQ是充分有效的和高等級的,甚至當線程池是不重要的時候,你也會想使用它們去協助處理多線程。

    現在我們簡單的看一下我們怎樣使用Task類來實現一個簡單的運行在線程池上的委托。

    當使用線程池時需要注意下面的事情:

  • 你不能設置一個線程的名字,因為設置線程的名字將會使調試更困難(當你在VS線程窗口中調試時,即使你可以附加一個描述)。
  • 線程池中的線程總是后臺線程(這通常不是問題)。
  • 在應用程序的開始期間,阻塞一個線程可能會觸發一個延遲,除非你調用ThreadPool.SetMinThreads
  • 你不能任意地改變池中的線程的優先級-因為當它釋放會池中的時候,優先級會被還原為正常狀態。

    你可以通過屬性Thread.CurrentThread.IsThreadPoolThread的屬性查詢線程是否是正在運行的一個池中的線程

    回到頂部

    二、通過TPL進入線程池

    你可以使用在TaskParallel Library中的Task類來輕松的進入線程池。這個Task類在Framework 4.0中有介紹:如果你對老的結構比較熟悉,考慮用非泛型的Task類替換ThreadPool.QueueUserWorkItem,將Asunchoronous?delgates替換為泛型Task<TResult>。最新的結構速度更快,更方便,而且更復雜。

    為了使用非泛型的任務類,調用Task.Factory.StartNew方法,將方法傳進委托中。

    Task.Factory.StartNew會返回一個Task對象,你可以使用它去監控這個task,比如,你可以調用它的wait方法等待它直到它完成。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    static?void?Main(string[] args)

    {

    ????Task task =? Task.Factory.StartNew(Go);

    ????task.Wait();

    ????Console.ReadKey();

    }

    ?

    static?void?Go()

    {

    ????Console.WriteLine("From the thread pool start...");

    ????Thread.Sleep(3000);

    ????Console.WriteLine("From the thread pool end");

    }

    當你調用task的Wait?方法時,一個未處理的異常會很容易地重新拋出到宿主線程上。(如果你不調用Wait方法而是放棄這個task,一個未處理的異常將會關閉掉這個進程)

    泛型Task<Tresult>類是非泛型Task的子類。它讓你從這個已經完成執行的task中得到一個返回值。在下面的例子中,我們使用Task<TResult>來下載一個web page

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    static?void?Main(string[] args)

    {

    ????Task<string> task = Task.Factory.StartNew<string>(

    ????????() => DownloadString("http://www.baidu.com"));

    ????//調用其他方法

    ????//

    ?

    ????//可以用task的Result的屬性來獲得task返回值。

    ????//如果這個任務還在運行,當前的主線程將會被阻塞,直到這個任務完成。

    ????string?result = task.Result;

    }

    ?

    static?string?DownloadString(string?uri)

    {

    ????using(var?wc =?new?System.Net.WebClient())

    ????{

    ????????return?wc.DownloadString(uri);

    ????}

    }

    Task Parallel Library有許多的功能,特別是提升多核處理器的性能。我們會在并行編程中繼續討論TPL。

    回到頂部

    三、不用TPL進入到線程池

    如果你的應用程序是.NET Framework的早期版本(4.0之前的版本),你將不能使用TPL。你必須使用老的結構進入線程池:

    ThreadPool.QueueUserWorkItemasynchoronous?delegates.兩者的不同點是asynchronous?delegates讓你從線程那里返回數據。Asynchronous?delegates收集任何exception返回給調用者。

    要使用QueueUserWorkItem,只需調用這個方法的運行在線程池上的委托。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    static?void?Main(string[] args)

    {

    ????ThreadPool.QueueUserWorkItem(Go);

    ????ThreadPool.QueueUserWorkItem(Go, 123);

    ????Console.ReadKey();

    }

    ?

    static?void?Go(object?data)

    {

    ????Console.WriteLine("A from thread pool! "?+ data);

    }

    我們的目標方法Go,必須接收一個簡單object類型的參數(為了滿足waitCallBack委托)。這將提供一個簡單的方式傳遞數據到方法中,就像是ParameterizedThreadStart。不像Task,QueueUserWorkItem不會返回一個對象去幫助你之后管理執行。還有,你必須顯式在目標方法的代碼中寫處理異常的代碼-因為未處理的異常將會終止程序。

    ?ThreadPool.QueueUserWorkItem沒有提供從一個已經完成的線程中得到它的返回值的機制。Asynchronous?delegate invocations(asynchronous delegates for short)解決了這個問題,允許任何個數類型化的參數在兩個方向傳遞。此外,在asynchronous delegates上未處理的異常很方便地在原始線程上重新拋出(更準確地說,這個線程叫做EndInvoke),因此不需要顯示處理。

    不要混淆asynchronous delegates和asynchronous method(方法以Begin和End開頭的,比如File.BeginRead/File.EndRead)。Asynchronous methods表面上按照簡單的協議,但是它們的存在是為了解決一個更困難的問題。

    下面是怎樣通過一個asynchronous delegate開始一個worker task:

  • 實例化一個委托,該委托針對你想要并行運行的method(典型的是預定義Func delegates其中的一種)。
  • 在delegate上調用BeginInvoke,保存它的IAsyncResult返回值。BeginInvoke立即返回給調用者。當其他池中的線程正在運行的時候,你可以執行其他動作。
  • 當你需要這個結果,在delegate上調用EndInvoke,傳遞已保存的IAsyncResult對象。
  • 在下面的例子中,我們使用一個asynchronous delegate invocation運行一個與主線程同時運行的簡單方法,這個方法返回一個字符串的長度:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    static?void?Main(string[] args)

    {

    ????Func<string,?int> t = Go;

    ????IAsyncResult result = t.BeginInvoke("test",?null,?null);

    ????//

    ????// ... 這里可以執行其他并行的任務

    ????//

    ?

    ????int?length = t.EndInvoke(result);

    ????Console.WriteLine("String lenth is: "?+ length);

    ????Console.ReadKey();

    }

    ?

    static?int?Go(string?messsage)

    {

    ????return?messsage.Length;

    }

    EndInvoke做三件事情。第一,如果asynchronous delegate沒有完成執行,則一直等待它完成。第二,接收返回值(以及任何ref或者out參數)。第三,返回任何未處理的線程異常給調用它的線程。

    注意:如果你用asynchronous delegate調用的方法沒有返回值,你在技術上需要調用EndInvoke。在實踐中,這是開放的辯論;沒有Endinvoke報警去管理處罰未編譯者!如果你選擇不去調用EndInvoke,然而,你需要考慮在線程的異常去避免靜默失敗。

    當你調用BeginInvoke方法時,可以指定一個call back delegate-一個可以接收一個IAsyncResult?對象的方法,它會在委托方法完成后被自動調用這個允許正在發動的線程忘記asynchronous delegate,但它在call back結束時需要一點額外的工作。

    v寫在最后

    線程池的使用的提升還沒有寫,最近兩年作息不規律,程序員得養好身體,早睡早起,睡覺睡覺。希望這篇博客能幫到大家,希望得到園友們的支持!


    作  者:?Jackson0714?
    出  處:http://www.cnblogs.com/jackson0714/?
    關于作者:專注于微軟平臺的項目開發。如有問題或建議,請多多賜教!?
    版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。?
    特此聲明:所有評論和私信都會在第一時間回復。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我?

    總結

    以上是生活随笔為你收集整理的C#多线程之旅(3)——线程池的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 五月开心网 | 色之久久综合 | 欧美夫妇交换xxx | 日本高清在线播放 | 欧美一区二区三区黄色 | 香蕉人妻av久久久久天天 | 国产精品久久久久久久妇 | 51吃瓜网今日吃瓜 | 亚洲经典在线观看 | 无码一区二区三区免费视频 | 九九视频在线观看 | 中文字幕线人 | 欧美色综合色 | 成人玩具h视频 | 欧美xxxxx牲另类人与 | 天天干天天插天天操 | 老头老太做爰xxx视频 | 337p粉嫩大胆噜噜噜亚瑟影院 | 黑人巨大猛烈捣出白浆 | 国语精品久久 | 久久久久亚洲日日精品 | 国产毛片视频网站 | 亚洲精品少妇一区二区 | 加勒比不卡视频 | 欧美大片在线播放 | 国产欧美精品一区二区三区app | 性饥渴的农村熟妇 | 嫩草在线观看视频 | 亚洲情网 | 欧美13p | 汗汗视频 | 精品一区视频 | 人妻精品久久久久中文 | 久久3p| 精品成人免费一区二区在线播放 | 污片网站在线观看 | 国产清纯白嫩初高中在线观看性色 | 成人另类小说 | 极品美女啪啪 | 国产91清纯白嫩初高中在线观看 | 蜜臀av一区 | 成人国产精品一区 | 日韩电影在线一区 | 午夜电影一区 | 亚洲一区欧美激情 | 中文字幕在线播放一区 | 久久成人精品视频 | 欧美三级午夜理伦三级老人 | 国产精品成人99一区无码 | 久久久久亚洲av无码a片 | 国产在线123| 精品一区二区三区蜜臀 | 播播成人网 | 国产伦精品一区二区三区高清版禁 | 日本一区二区三区精品视频 | 亚色一区 | 久久精品视频18 | 午夜特片网 | 日韩不卡高清视频 | 久久国产麻豆 | 亚洲一级在线观看 | 美女毛毛片| 一本色道无码道dvd在线观看 | 亚洲欧美日韩成人在线 | 高清av一区 | 国产精品国产馆在线真实露脸 | 特黄aaaaaa私密按摩 | 农村搞破鞋视频大全 | 成人妇女淫片aaaa视频 | 日本久色 | 性――交――性――乱 | 久久视频精品 | 污网站免费在线观看 | 久久视频在线观看免费 | 欧美一级黄色网 | 少妇做爰k8经典 | 黄色午夜网站 | 插插插综合 | 午夜精品久久久久久久91蜜桃 | 久久这里都是精品 | 亚洲啪视频 | 青草热视频 | 亚洲成人777 | 天天综合中文字幕 | 国产精品天干天干 | 91精品国产91久久久 | 色女综合 | 午夜色福利| 91视频在线网站 | www国产在线 | 毛片在线免费播放 | 麻豆精品免费观看 | 国产二区精品视频 | av大帝| 欧美成人午夜影院 | 国产乱xxⅹxx国语对白 | 亚洲AV成人无码久久精品同性 | 热热久| 欧美日韩一 |