在C#多線程之線程池篇中,我們將學(xué)習(xí)多線程訪問(wèn)共享資源的一些通用的技術(shù),我們將學(xué)習(xí)到以下知識(shí)點(diǎn):

  • 在線程池中調(diào)用委托

  • 在線程池中執(zhí)行異步操作

  • 線程池和并行度

  • 實(shí)現(xiàn)取消選項(xiàng)

  • 使用等待句柄和超時(shí)

  • 使用計(jì)時(shí)器

  • 使用后臺(tái)工作組件

  在前面的“C#多線程之基礎(chǔ)篇”以及“C#多線程之線程同步篇”中,我們學(xué)習(xí)了如何創(chuàng)建線程以及如何使用多線程協(xié)同工作,在這一篇中,我們將學(xué)習(xí)另外一種場(chǎng)景,就是我們需要?jiǎng)?chuàng)建許多花費(fèi)時(shí)間非常短的異步操作來(lái)完成某些工作。我們知道創(chuàng)建一個(gè)線程是非常昂貴的,因此,對(duì)于每個(gè)花費(fèi)時(shí)間非常短的異步操作都創(chuàng)建一個(gè)線程是不合適的。

  我們可以使用線程池來(lái)解決以上問(wèn)題,我們可以在線程池中分配一定數(shù)量的線程,每當(dāng)我們需要一個(gè)線程時(shí),我們只需要在線程池中取得一個(gè)線程即可,而不需要?jiǎng)?chuàng)建一個(gè)新的線程,當(dāng)我們使用完一個(gè)線程時(shí),我們僅僅需要把線程重新放入線程池中即可。

  我們可以使用System.Threading.ThreadPool類(lèi)型來(lái)利用線程池。線程池由Common Language Runtime(CLR)進(jìn)行管理,這意味著每一個(gè)CLR只能有一個(gè)線程池實(shí)例。ThreadPool類(lèi)型有一個(gè)“QueueUserWorkItem”靜態(tài)方法,這個(gè)靜態(tài)方法接收一個(gè)委托,該委托代表一個(gè)用戶(hù)自定義的異步操作。當(dāng)這個(gè)方法被調(diào)用時(shí),這個(gè)委托就進(jìn)入內(nèi)部隊(duì)列,這個(gè)時(shí)候,如果線程池中沒(méi)有線程,則會(huì)創(chuàng)建一個(gè)新的工作線程,然后將這個(gè)委托(第一個(gè))放入隊(duì)列中。

  如果先前的操作執(zhí)行完畢后,我們又放置了一個(gè)新的操作到線程池,那么我們可能會(huì)重用上一次操作的那個(gè)工作線程。如果我們放置新的操作的時(shí)候,線程池中的線程數(shù)已達(dá)到上限,那么新的操作會(huì)在隊(duì)列中等待,直到線程池中有可用工作線程為止。

  需要注意的是,我們盡量在線程池中放置一些需要花費(fèi)較少時(shí)間既能完成的操作,而不要放置需要花費(fèi)大量時(shí)間才能完成的操作,同時(shí)不要阻塞工作線程。如果不是這樣,工作線程會(huì)變得非常繁忙,以至于不能響應(yīng)用戶(hù)操作,同時(shí)也會(huì)導(dǎo)致性能問(wèn)題以及難以調(diào)試的錯(cuò)誤。

  另外,線程池中的工作線程都是