1. 程式人生 > >win10 uwp 線程池

win10 uwp 線程池

大於 zh-cn 線程池。 sync adl post runas 可能 pos

原文:win10 uwp 線程池

如果大家有開發 WPF 或以前的程序,大概知道線程池不是 UWP 創造的,實際上在很多技術都用到線程池。 為什麽需要線程池,他是什麽?如何在 UWP 使用線程池,本文就是來告訴大家這些

目錄
  1. 為什麽需要線程池
  2. 什麽是線程池
  3. 線程池原理
  4. 應用
  5. 等待代碼完成
  6. 定時器

為什麽需要線程池

在程序中,創建和銷毀線程是需要很多資源的,如果只是為了完成很小的代碼而創建一個新的線程,創建線程占用的時間在總的運行時間占有比例很大。所以大神就說,那就不創建線程了。

因為花費總時間劃不來,所以大神就想直接創建一個線程,也不銷毀,一旦用戶需要一個新線程去做一些事情,就把這個線程給他。這樣就可以省略了創建和銷毀線程時間,減少了花費總時間。

什麽是線程池

百度說線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然後在創建線程後自動啟動這些任務。

在 C# 中,線程池只是預先分配了一些線程,線程沒事做就休息,有工作需要就隨便叫一個線程出來。通過這個方法減少創建線程的時間。

線程池原理

在 C# 大家都知道,執行一個方法,如果需要把方法傳到另一個時間去調用,就可以使用委托。而創建一個線程去做其他的事情,實際上可以認為是把一個委托傳入一個線程,讓這個線程使用。線程池就是先創建了很多線程,用戶調用就是傳入方法,線程池拿出一個空閑的線程去執行傳入的方法。

最簡單的模擬代碼就是創建一個線程,然後讓他運行一個委托,運行完成設置這個委托為空。

        private Action _action;

            new Thread(() =>
            {
                while (true)
                {
                    _action?.Invoke();
                    _action = null;
                }
            }).Start();

上面代碼是無法在 UWP 運行的,只是告訴大家原理。

因為做這個線程池需要很多代碼,如判斷設備運行多少個線程合適,分配空閑線程等。好像微軟已經弄好了,大家只需要用。

應用

大家從原理可以知道,線程池運行代碼,不是立刻運行的,假如線程池有10個線程,剛好都在做其他事情,這時請線程池運行新的代碼,就會等待線程池存在空閑線程。

千萬不要使用線程池執行比較緊急的任務,因為可能等待很多時間都沒運行。

在 UWP 可以通過 ThreadPool 使用線程池。

            var thread = ThreadPool.RunAsync(e =>
            {
                Debug.WriteLine("使用線程池很簡單");
            });

使用的方法十分簡單,傳入一個委托就可以。

等待代碼完成

很多時候的線程模型就是需要運行很多並行代碼,在運行完成再運行串行的代碼。

技術分享圖片

這時就需要使用線程池運行代碼,還需要等待代碼運行完成

例如我需要下載 lindexi.github.io 所有博客,獲得所有文章只能使用一個線程獲取,但是下載所有博客就可以並行。在所有下載完成還需要告訴用戶,這時只能使用一個線程。

            var url = "lindexi.github.io";

            // 獲取所有文章
            var aritcle = GetArticle(url);

            var threadList = new List<IAsyncAction>();

            foreach (var temp in aritcle)
            {
                threadList.Add(ThreadPool.RunAsync(e =>
                {
                    Download(temp);
                }));
            }

            Task.WaitAll(threadList.Select(temp => temp.AsTask()).ToArray());

            Debug.WriteLine("下載完所有博客");

定時器

如果需要一個定時器,除了使用主線程的定時器,還可以使用 ThreadPoolTimer ,創建一個定時器很簡單,請看代碼

            ThreadPoolTimer.CreateTimer(timer =>
            {
                Debug.WriteLine("下載完所有博客");
            }, new TimeSpan(0, 0, 0, 1));

實際上從效果,可以把上面的代碼認為是

            Task.Delay(new TimeSpan(0, 0, 0, 1)).ContinueWith(_ =>
            {
                Debug.WriteLine("下載完所有博客");
            });

如果需要重復執行,請使用 CreatePeriodicTimer ,這個函數可以延遲大於指定的時間執行代碼

            ThreadPoolTimer.CreatePeriodicTimer(timer =>
            {
                Debug.WriteLine("下載完所有博客");
            }, new TimeSpan(0, 0, 0, 1));

如果想讓軟件代碼不會被大神噴,那麽請看一下使用線程池的最佳做法


本文會經常更新,請閱讀原文: https://lindexi.gitee.io/lindexi/post/win10-uwp-%E7%BA%BF%E7%A8%8B%E6%B1%A0.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。

技術分享圖片 本作品采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含鏈接: https://lindexi.gitee.io ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發布。如有任何疑問,請 與我聯系 。

win10 uwp 線程池