WPF高級學習(一)

文章目錄

  • 一、理解進程和線程
      • 1. 進程:就像一個獨立的“工廠”
        • 舉例:
      • 2. 線程:就像工廠里的“工人”
        • 舉例:
      • 總結:進程 vs 線程
  • 二、線程
      • 一、WPF 中的線程類型
      • 二、核心規則:線程親和性(Thread Affinity)
      • 三、線程間通信的核心:Dispatcher
        • 1. Dispatcher 的工作原理
        • 2. 常用方法(見下表)
      • 四、線程使用示例
      • 五、常見線程問題及解決方案
      • 六、與其他技術的對比
      • 總結
  • 三、Dispatcher
      • 一、Dispatcher 的核心作用
      • 二、Dispatcher 的關鍵方法
      • 三、使用場景與實例
        • 1. 基礎用法:獲取 Dispatcher 實例
        • 2. 后臺線程更新 UI(使用 `InvokeAsync`)
        • 3. 帶優先級的操作
        • 4. 同步執行(`Invoke`)
      • 四、注意事項
      • 總結
  • 四、WPF里的線程和進程
      • 1. WPF中的進程:就像“整個劇院”
      • 2. WPF中的線程:就像“劇院里的工作人員”
        • (1)UI線程:“舞臺總監”
        • (2)后臺線程:“后臺工作人員”
      • 關鍵區別:WPF線程 vs 普通Windows線程
        • 舉例:WPF中下載圖片并顯示
      • 總結
  • 五、UI線程的簡單使用說明
      • 一、UI線程的“樣子”:它不是一個可見的實體,而是一種“執行角色”
      • 二、如何“使用”UI線程?
        • 1. 默認情況下:代碼運行在UI線程中
        • 2. 后臺線程如何與UI線程通信?
        • 3. 如何判斷當前線程是否是UI線程?
      • 三、錯誤示例:后臺線程直接操作UI(會崩潰)
      • 總結

一、理解進程和線程

在Windows系統中,進程線程是管理程序運行的兩個核心概念,我們可以用“工廠”和“工人”來生動類比:

參考鏈接
一文帶你搞懂C#多線程的5種寫法

1. 進程:就像一個獨立的“工廠”

  • 定義:進程是一個正在運行的程序(比如微信、記事本、瀏覽器),它擁有自己的“地盤”(獨立的內存空間、資源),是系統分配資源的基本單位。
  • 特點:每個進程之間相互隔離,就像不同工廠之間用圍墻隔開,彼此的資源(原材料、設備)不共享,一個工廠出問題(崩潰)不會直接影響其他工廠。
舉例:
  • 當你打開“記事本”時,Windows會創建一個記事本進程:
    • 它會占用一塊獨立的內存(用來存你輸入的文字);
    • 擁有自己的窗口資源(標題欄、輸入區);
    • 即使你再打開一個新的記事本(另一個進程),兩個記事本的內容也不會互相干擾(各自內存獨立)。
  • 同理,你同時打開“微信”和“瀏覽器”,它們就是兩個獨立的進程,微信的內存數據(聊天記錄)和瀏覽器的內存數據(網頁緩存)完全分開。

2. 線程:就像工廠里的“工人”

  • 定義:線程是進程內部的“執行單元”,一個進程至少有一個線程(主線程),也可以有多個線程,它們共享進程的資源(內存、設備等),是系統調度執行的基本單位。
  • 特點:線程更輕量,多個線程在同一個進程內協作,就像工廠里的多個工人共用工廠的設備和原材料,效率更高,但需要協調工作(避免搶資源)。
舉例:
  • 用“瀏覽器進程”來說:
    • 當你打開一個瀏覽器(比如Chrome),它首先會創建一個主線程(相當于“廠長”),負責顯示窗口、處理地址欄輸入等。
    • 你在瀏覽器里同時做三件事:
      1. 下載一個文件(線程A:專門負責網絡下載,相當于“搬運工”);
      2. 播放網頁里的視頻(線程B:專門負責視頻解碼,相當于“播放員”);
      3. 拖動頁面滾動條(線程C:專門負責界面刷新,相當于“清潔工”)。
    • 這三個線程都屬于瀏覽器進程,共享瀏覽器的內存(比如下載的文件臨時存在瀏覽器的緩存區),但各自干不同的活,讓你感覺“同時”完成了多個操作。
  • 再比如“微信”進程:
    • 一個線程負責接收消息(監聽網絡),另一個線程負責刷新聊天窗口(顯示新消息),還有一個線程負責檢查更新——它們共享微信的賬號數據、聊天記錄(存在進程的內存里),協作完成微信的所有功能。

總結:進程 vs 線程

類比進程(工廠)線程(工人)
資源有獨立內存、資源(圍墻內的地盤)共享進程的資源(共用工廠設備)
獨立性相互隔離,一個崩潰不影響其他同屬一個進程,一個線程崩潰可能拖垮整個進程
數量系統中可同時存在多個獨立進程一個進程可包含多個線程
核心作用作為資源分配的單位作為任務執行的單位

簡單說:進程是“容器”,線程是“干活的”。一個進程里的多個線程協同工作,讓程序能高效處理多任務;而多個進程則保證了不同程序之間的安全隔離。

二、線程

在 WPF 中,線程模型是其核心特性之一,尤其是與 UI 交互相關的線程規則,直接影響應用程序的穩定性和性能。以下是 WPF 線程模型的詳細介紹:
深入淺出C#:章節 9: C#高級主題:多線程編程和并發處理

一、WPF 中的線程類型

WPF 應用程序通常涉及兩種主要線程:

  1. UI 線程(主線程)

    • 是應用程序啟動時自動創建的線程,負責創建和管理所有 UI 元素(如 WindowButtonTextBox 等)。
    • 處理用戶輸入(鼠標、鍵盤事件)、UI 渲染和布局計算。
    • 特點:一個 WPF 應用程序只有一個 UI 線程,所有 UI 操作必須在該線程上執行。
  2. 后臺線程(工作線程)

    • 由開發者手動創建(如通過 TaskThread 等),用于執行耗時操作(如數據計算、文件讀寫、網絡請求、串口通信等)。
    • 特點:不能直接操作 UI 元素,否則會拋出 InvalidOperationException(跨線程操作異常)。

二、核心規則:線程親和性(Thread Affinity)

WPF 控件具有線程親和性

  • 控件只能由創建它的線程(即 UI 線程)訪問或修改其屬性(如 TextVisibilityWidth 等)。
  • 后臺線程若要操作 UI,必須通過 Dispatcher(UI 線程的調度器)將操作“委托”給 UI 線程執行。

為什么有這個規則?
WPF 的渲染引擎和布局系統不是線程安全的,單線程處理 UI 可以避免多線程并發修改導致的界面錯亂或崩潰。

三、線程間通信的核心:Dispatcher

Dispatcher 是 UI 線程的“調度中心”,負責管理 UI 線程的工作項隊列,是后臺線程與 UI 線程通信的唯一安全方式。

1. Dispatcher 的工作原理
  • UI 線程運行時會不斷從 Dispatcher 的隊列中取出工作項并執行。
  • 后臺線程通過 Dispatcher 的方法(如 InvokeAsyncBeginInvoke)將 UI 操作封裝成工作項,加入隊列。
  • Dispatcher 按優先級依次執行這些工作項,確保它們在 UI 線程上運行。
2. 常用方法(見下表)
方法作用適用場景
Invoke(Action)同步執行:阻塞當前線程,直到 UI 線程完成操作需要等待 UI 操作結果(如彈窗確認)
BeginInvoke(Action)異步執行:不阻塞當前線程,操作入隊后立即返回無需等待結果的 UI 更新(如顯示日志)
InvokeAsync(Action)異步執行:返回 Task,支持 await(推薦)現代異步編程模式,兼顧簡潔性和可控性

四、線程使用示例

以“后臺計算 + UI 實時更新”為例:

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();// 啟動后臺任務StartBackgroundWork();}private void StartBackgroundWork(){// 創建后臺線程(Task 自動管理線程池)Task.Run(() =>{for (int i = 0; i <= 100; i++){// 模擬耗時計算Thread.Sleep(100);int progress = i;// 關鍵:通過 Dispatcher 委托 UI 更新// 方法1:使用 InvokeAsync(推薦,支持 await)Dispatcher.InvokeAsync(() =>{// 此代碼在 UI 線程執行,安全更新進度條progressBar.Value = progress;txtStatus.Text = $"進度:{progress}%";});// 方法2:使用 BeginInvoke(無返回值,純異步)// Dispatcher.BeginInvoke(new Action(() =>// {//     progressBar.Value = progress;// }));}});}
}

五、常見線程問題及解決方案

  1. 跨線程操作異常

    • 錯誤表現:后臺線程直接修改 TextBox.Text 等屬性,拋出 InvalidOperationException
    • 解決:通過 Dispatcher 調度 UI 操作(如上述示例)。
  2. UI 線程阻塞

    • 錯誤表現:在 UI 線程執行耗時操作(如下載大文件),導致界面卡頓、無響應。
    • 解決:將耗時操作移到后臺線程,僅通過 Dispatcher 傳遞結果到 UI 線程。
  3. Dispatcher 優先級問題

    • 問題:低優先級操作(如日志記錄)可能被高優先級操作(如用戶輸入)阻塞。
    • 解決:通過 DispatcherPriority 控制優先級,例如:
      // 高優先級:優先更新進度
      Dispatcher.InvokeAsync(() => { progressBar.Value = 50; }, DispatcherPriority.Normal);
      // 低優先級:空閑時再執行日志
      Dispatcher.InvokeAsync(() => { LogToFile("進度50%"); }, DispatcherPriority.Background);
      

六、與其他技術的對比

  • WinForms:也有單線程 UI 模型,但線程檢查較寬松(默認允許跨線程操作,僅拋出警告),而 WPF 強制禁止。
  • UWP/MAUI:線程模型類似 WPF,同樣依賴 Dispatcher 實現線程間通信,但 API 略有差異(如 DispatcherQueue)。

總結

WPF 的線程模型核心是“單 UI 線程 + 多后臺線程”,通過 Dispatcher 實現安全的線程間通信。關鍵原則是:

  • 耗時操作放后臺線程,避免阻塞 UI。
  • UI 操作必須在 UI 線程執行,通過 Dispatcher 調度。

掌握這一模型是開發流暢、穩定的 WPF 應用的基礎,尤其在處理串口通信、網絡請求、大數據計算等場景時至關重要。

三、Dispatcher

在 WPF 中,Dispatcher 是處理線程與 UI 交互的核心機制,它確保所有 UI 操作都在創建 UI 元素的線程(通常是主線程) 上執行,避免跨線程操作導致的異常。下面詳細介紹其用法和實例:

一、Dispatcher 的核心作用

WPF 控件具有線程親和性:只有創建控件的線程(主線程)才能修改其屬性(如 TextVisibility 等)。如果后臺線程直接操作 UI,會拋出 InvalidOperationException

Dispatcher 的作用是:

  • 管理 UI 線程的工作項隊列
  • 允許其他線程將 UI 操作“委托”給主線程執行
  • 控制操作的優先級

二、Dispatcher 的關鍵方法

方法說明
Invoke(Action)同步執行:阻塞當前線程,直到 UI 線程完成操作
BeginInvoke(Action)異步執行:不阻塞當前線程,操作加入隊列后立即返回
InvokeAsync(Action)異步執行:返回 Task,支持 await(推薦)

三、使用場景與實例

以串口通信為例,后臺線程接收數據后需要更新 UI 顯示,這是 Dispatcher 的典型應用場景。

1. 基礎用法:獲取 Dispatcher 實例

通常在主線程(如窗口構造函數)中保存 Dispatcher 實例,供后臺線程使用:

public partial class MainWindow : Window
{private Dispatcher _uiDispatcher;private SerialPort _serialPort;public MainWindow(){InitializeComponent();// 獲取當前 UI 線程的 Dispatcher(主線程)_uiDispatcher = Dispatcher.CurrentDispatcher;}
}
2. 后臺線程更新 UI(使用 InvokeAsync

假設串口數據接收在后臺線程,需要將數據顯示到 TextBox 中:

// 模擬后臺線程接收串口數據
private void StartReceivingData()
{// 啟動后臺線程Task.Run(() =>{while (true){// 模擬接收數據(實際中是 _serialPort.Read())string receivedData = $"收到數據:{DateTime.Now:HH:mm:ss}\r\n";// 關鍵:通過 Dispatcher 將 UI 操作委托給主線程_uiDispatcher.InvokeAsync(() =>{// 這部分代碼會在主線程執行,安全更新 UItxtReceivedData.AppendText(receivedData);// 滾動到最新內容txtReceivedData.ScrollToEnd();});// 模擬接收間隔Thread.Sleep(1000);}});
}
3. 帶優先級的操作

Dispatcher 支持設置操作優先級(DispatcherPriority),高優先級的操作會先執行:

// 高優先級:立即更新狀態文本
_uiDispatcher.InvokeAsync(() =>
{lblStatus.Text = "正在接收數據...";
}, DispatcherPriority.Normal);// 低優先級:耗時的日志記錄(不會阻塞緊急 UI 更新)
_uiDispatcher.InvokeAsync(() =>
{LogToFile(receivedData);
}, DispatcherPriority.Background);

常見優先級(從高到低):

  • Send:立即執行(最高)
  • Normal:默認優先級
  • Background:低于正常 UI 操作
  • SystemIdle:系統空閑時執行(最低)
4. 同步執行(Invoke

如果需要等待 UI 操作完成后再繼續(如彈窗確認),使用 Invoke

// 后臺線程中需要用戶確認
private void ShowConfirmation()
{bool? result = _uiDispatcher.Invoke(() =>{// 同步顯示彈窗(會阻塞當前后臺線程,直到用戶點擊)return MessageBox.Show("是否繼續接收數據?", "確認", MessageBoxButton.YesNo);});if (result == false){// 停止接收邏輯}
}

四、注意事項

  1. 避免濫用 Invoke:同步執行會阻塞后臺線程,可能導致性能問題,優先使用 InvokeAsync
  2. 不要在 UI 線程中調用 Dispatcher:主線程可以直接操作 UI,無需通過 Dispatcher
  3. 釋放資源:后臺線程退出時,需停止 Dispatcher 相關的循環操作,避免內存泄漏。
  4. 替代方案:在 MVVM 模式中,可使用 BindingOperations.EnableCollectionSynchronizationObservableCollection 的線程安全變體,但本質仍是基于 Dispatcher

總結

Dispatcher 是 WPF 中多線程與 UI 交互的“橋梁”,核心用法是通過 InvokeAsync(推薦)或 BeginInvoke 將后臺線程的 UI 操作委托給主線程,確保界面安全更新。在串口通信、網絡請求、定時任務等場景中必不可少。

四、WPF里的線程和進程

在WPF(Windows Presentation Foundation)中,線程和進程的基本概念與Windows系統一致(進程是程序運行的容器,線程是執行單元),但WPF對線程有特殊的UI線程約束,這是理解WPF線程模型的核心。

可以用“劇院演出”來類比:

1. WPF中的進程:就像“整個劇院”

  • 當你運行一個WPF程序(如一個桌面應用),Windows會為它創建一個獨立進程。
  • 這個進程包含了程序所需的所有資源:代碼、內存、窗口資源、UI控件(按鈕、文本框等)的狀態數據等,就像劇院包含舞臺、道具、演員休息室等所有設施。
  • 進程間相互隔離,比如你同時打開兩個WPF程序(如兩個不同的記事本應用),它們是兩個獨立進程,一個崩潰不會影響另一個。

2. WPF中的線程:就像“劇院里的工作人員”

WPF程序的進程中至少有兩個關鍵線程(可能更多):

(1)UI線程:“舞臺總監”
  • 唯一負責UI操作:WPF規定,所有UI元素(按鈕、窗口、動畫等)的創建、更新、事件響應(如點擊按鈕)必須由同一個線程處理,這個線程就是UI線程。
  • 類比:就像舞臺總監,所有舞臺上的調度(演員上場、燈光變化、場景切換)必須經過他,別人不能直接指揮,否則會亂套。
  • 例子:當你在WPF窗口上點擊一個按鈕,按鈕的Click事件只能在UI線程中處理;你想更新一個文本框的內容(TextBox.Text = "新內容"),也必須在UI線程中執行。
(2)后臺線程:“后臺工作人員”
  • 處理耗時任務:如果有耗時操作(如下載文件、計算大數據),不能放在UI線程中執行,否則會導致UI卡頓(就像舞臺總監跑去搬道具,沒人指揮舞臺,演出會暫停)。
  • 類比:就像劇院里的燈光師、化妝師,他們在后臺工作(不直接指揮舞臺),但可以通過“消息”告訴舞臺總監結果(比如“燈光已準備好”)。
  • 例子:在WPF中,你可以用TaskThread創建后臺線程來下載圖片,下載完成后,必須通過Dispatcher(WPF的線程通信工具)“通知”UI線程更新圖片控件的顯示。

關鍵區別:WPF線程 vs 普通Windows線程

普通Windows程序(如控制臺應用)的線程可以隨意操作資源,但WPF有嚴格的UI線程綁定

  • UI元素(如ButtonWindow)被“綁定”到創建它們的UI線程,其他線程不能直接修改它們。
  • 如果后臺線程想更新UI,必須通過Dispatcher.InvokeDispatcher.BeginInvoke向UI線程“提交任務”,由UI線程處理。
舉例:WPF中下載圖片并顯示
  1. 啟動WPF程序,創建進程,同時創建UI線程(負責顯示窗口和按鈕)。
  2. 用戶點擊“下載圖片”按鈕:
    • 按鈕的Click事件在UI線程中觸發。
    • UI線程創建一個后臺線程(避免卡頓),讓它去下載圖片(耗時操作)。
  3. 后臺線程下載完成后,不能直接修改圖片控件(Image.Source),而是通過Dispatcher告訴UI線程:“圖片下載好了,你去更新顯示吧”。
  4. UI線程收到消息后,在自己的執行隊列中處理這個任務,最終更新圖片顯示。

總結

  • WPF的進程是程序運行的獨立容器,包含所有資源,和系統進程概念一致。
  • WPF的線程中,UI線程是“特殊的”(唯一能操作UI),后臺線程負責耗時任務,兩者通過Dispatcher協作。

理解這個模型的核心是:WPF的UI元素是“單線程公寓”(STA),只能由創建它們的UI線程訪問,這是避免UI混亂的關鍵設計。

五、UI線程的簡單使用說明

在WPF中,更準確的說法是UI線程(屬于應用程序進程的一部分)。每個WPF應用程序的進程中會有一個專門負責UI交互的線程,我們通常稱之為“UI線程”。

一、UI線程的“樣子”:它不是一個可見的實體,而是一種“執行角色”

UI線程是WPF進程啟動時自動創建的線程,它的核心特征是:

  1. 負責所有UI元素的創建和更新:窗口、按鈕、文本框等控件的初始化、屬性修改、事件響應(如點擊、輸入)都必須在這個線程中執行。
  2. 擁有一個消息循環:不斷接收和處理用戶輸入(如鼠標點擊、鍵盤輸入)、系統通知(如窗口大小變化),并刷新UI顯示,就像一個“前臺接待員”,時刻處理與用戶的交互。
  3. 單線程特性:WPF的UI元素是“單線程公寓(STA)”模式,只能由創建它們的UI線程訪問,其他線程不能直接操作。

二、如何“使用”UI線程?

在WPF開發中,我們不需要手動創建UI線程(框架會自動創建),但需要理解如何正確與UI線程交互,尤其是在涉及后臺任務時。

1. 默認情況下:代碼運行在UI線程中

當你在WPF的事件處理函數(如按鈕點擊)或初始化代碼中操作UI時,代碼默認就在UI線程中執行:

// 按鈕點擊事件(默認在UI線程中執行)
private void Button_Click(object sender, RoutedEventArgs e)
{// 直接修改文本框內容(安全,因為在UI線程中)MyTextBox.Text = "按鈕被點擊了";
}
2. 后臺線程如何與UI線程通信?

如果有耗時操作(如下載、計算),需要放在后臺線程執行,完成后再通知UI線程更新界面。這時必須通過WPF的Dispatcher(UI線程的“消息調度器”)來實現:

步驟示例

private void StartLongTaskButton_Click(object sender, RoutedEventArgs e)
{// 1. 在UI線程中啟動一個后臺線程(避免阻塞UI)Task.Run(() => {// 這部分代碼在后臺線程執行(耗時操作)Thread.Sleep(3000); // 模擬耗時任務(如下載文件)string result = "任務完成!";// 2. 后臺線程不能直接更新UI,需通過Dispatcher通知UI線程MyTextBox.Dispatcher.Invoke(() => {// 這部分代碼由Dispatcher調度到UI線程執行MyTextBox.Text = result;});});
}

關鍵說明

  • Dispatcher是UI線程的“代理”,每個UI元素(如MyTextBox)都能通過Dispatcher屬性訪問到UI線程的調度器。
  • Invoke:同步等待UI線程執行任務(會阻塞后臺線程,直到UI更新完成)。
  • BeginInvoke:異步讓UI線程執行任務(不阻塞后臺線程,更常用)。
3. 如何判斷當前線程是否是UI線程?

可以通過Dispatcher.CheckAccess()方法判斷:

if (MyTextBox.Dispatcher.CheckAccess())
{// 當前在UI線程中,可直接操作UIMyTextBox.Text = "在UI線程中";
}
else
{// 不在UI線程中,需通過DispatcherMyTextBox.Dispatcher.BeginInvoke(() => {MyTextBox.Text = "通過Dispatcher更新";});
}

三、錯誤示例:后臺線程直接操作UI(會崩潰)

如果后臺線程直接修改UI元素,WPF會拋出異常(跨線程操作無效):

// 錯誤示例!會導致程序崩潰
private void BadButton_Click(object sender, RoutedEventArgs e)
{Task.Run(() => {// 后臺線程直接修改UI(禁止!)MyTextBox.Text = "這會報錯!"; });
}

總結

  • UI線程是WPF進程中自動創建的“UI管家”,負責所有界面相關操作。
  • 日常開發中,大部分UI操作(如事件處理、初始化)默認就在UI線程中,無需額外處理。
  • 后臺線程與UI交互必須通過Dispatcher,這是WPF線程模型的核心規則,遵守它才能避免界面卡頓或崩潰。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93286.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93286.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93286.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JAVA知識點(四):SpringBoot與分布式、微服務架構

文章目錄SpringBoot 使用 Validation 進行參數校驗并統一返回校驗異常引入相應的依賴Validation的基本校驗注解添加參數校驗在DTO的屬性上添加校驗在controller對應的DTO添加Valid或者Validated對于復雜String校驗我們可以使用正則來校驗&#xff0c;如下所示&#xff1a;自定義…

GPU 服務器ecc報錯處理

1. 常見原因分析內存硬件問題&#xff1a;DIMM 內存模塊損壞或接觸不良&#xff08;最常見原因&#xff09;。內存插槽氧化、松動或物理損壞。內存與主板兼容性問題&#xff08;尤其是非原廠內存&#xff09;。環境因素&#xff1a;服務器內部溫度過高&#xff0c;導致內存穩定…

STM32入門之通用定時器PWM

一、通用定時器簡介STM32通用定時器由一個通過可編程預分頻器驅動的16位自動重裝載計數器組成&#xff0c;適用于多種應用場景&#xff0c;包括測量輸入信號的脈沖長度&#xff08;利用輸入捕獲功能&#xff09;和生成輸出波形&#xff08;使用輸出比較及PWM功能&#xff09;。…

第十八節 MATLAB for循環

MATLAB中 for 循環是一個重復的控制結構&#xff0c;可以有效地寫一個循環&#xff0c;只是執行的次數是特定的。MATLAB for 循環語法:MATLAB中的 for循環的語法如下&#xff1a;for index values<program statements>... endfor 循環的值有下述三種形式之一&#xff1a…

嵌入式硬件篇---zigbee無線串口通信問題解決方法

針對 ZigBee 無線串口通信中接收異常的問題&#xff0c;需結合其射頻特性、網絡機制、硬件配置等多維度原因&#xff0c;采取針對性解決措施。以下從具體場景出發&#xff0c;提供可落地的解決方法&#xff1a;一、解決射頻層干擾與信號衰減問題射頻層是無線通信的基礎&#xf…

移動高清盒子6PRO-河南創維E900V22D-晶晨S905L3B-4+16G-安卓9-線刷固件包

移動高清盒子6PRO-河南創維E900V22D-晶晨S905L3B-416G-安卓9-線刷固件包線刷方法&#xff1a;1、準備好一根雙公頭USB線刷刷機線&#xff0c;長度30-50CM長度最佳&#xff0c;同時準備一臺電腦&#xff1b;2、電腦上安裝好刷機工具Amlogic USB Burning Tool 軟件 →打開軟件 →…

臺式電腦有多個風扇開機只有部分轉動的原因

一、風扇未連接或連接松動這是最常見的原因之一&#xff0c;臺式機風扇通常需要通過線材與主板或電源連接&#xff1a;主板接口問題&#xff1a;CPU 風扇、機箱風扇等多連接到主板的風扇接口&#xff08;如 CPU_FAN、SYS_FAN&#xff09;&#xff0c;若線材未插緊、插錯接口&am…

【測試報告】思緒網(Java+Selenium+Jmeter自動化測試)

一、項目簡介思緒網作為一種在線交流平臺&#xff0c;支持用戶在平臺下發布文章&#xff0c;并進行討論。主要由登錄頁面&#xff0c;論壇頁面&#xff0c;帖子編輯頁&#xff0c;帖子詳情頁等頁面組成。二、項目功能1.登錄頁面&#xff1a;輸入正確的賬號密碼進行登錄,跳轉博客…

Nestjs框架: 基于Mongodb的多租戶功能集成和優化

概述 基于前文&#xff0c;我們知道如何集成多租戶的相關功能了, 現在我們繼續集成Monodb的多租戶形式需要注意的是&#xff0c;MongoDB 在 NestJS 中的使用過程中存在一些“坑點”如果按照默認方式集成&#xff0c;會發現連接數在不斷增長&#xff0c;即使我們請求的是相同的數…

如何利用機器學習分析篩選生物標記物

在生物信息學中&#xff0c;Lasso回歸、隨機森林&#xff08;Random Forest&#xff09;和XGBoost因其各自的特性和優勢&#xff0c;被廣泛應用于基因組學、蛋白質組學、藥物發現和疾病機制研究等領域。 Lasso回歸 癌癥亞型分類&#xff1a;從TCGA數據中篩選驅動基因&#xf…

計算機網絡(基礎篇)

TCP/IP 網絡模型 應用層&#xff08;Application Layer&#xff09; 應用層只需要專注于為用戶提供應用功能&#xff0c;比如 HTTP、FTP、Telnet、DNS、SMTP等。應用層是工作在操作系統中的用戶態&#xff0c;傳輸層及以下則工作在內核態。傳輸層&#xff08;Transport Layer&a…

全面解析 CSS Flex 布局:從入門到精通的所有屬性詳解

1. Flex 容器屬性 通過 display: flex 或 display: inline-flex 將元素設置為 Flex 容器。以下是所有容器屬性。 1.1 display: flex | inline-flex 作用&#xff1a;定義一個 Flex 容器。可選值&#xff1a; flex&#xff1a;塊級容器&#xff0c;占據整行。inline-flex&#x…

數據結構:對角矩陣(Diagonal Matrix)

目錄 矩陣的傳統表示&#xff1a;二維數組 &#x1f50d; 真正有用的數據是哪些&#xff1f; 從二維數組轉為一維數組 用 C 類實現對角矩陣 1. 對角矩陣真正需要存什么&#xff1f; 2. 對角矩陣允許哪些行為&#xff1f; 3. 為什么要動態分配數組&#xff1f; 接下來推…

Leetcode_349.兩個數組的交集

這道題的意思很明確&#xff0c;就是讓尋找兩個數組中的共同元素&#xff0c;并去重&#xff0c;由此可以聯想到哈希表的特性&#xff0c;注意到題目給的數據范圍&#xff0c;在1000以內&#xff0c;所以本題可以使用 STL 的庫函數&#xff0c;也可以使用數組進行模擬。 本題要…

STM32——寄存器映射

總 &#xff1a;STM32——HAL庫總結-CSDN博客 芯片資料&#xff1a; STM32F1系列參考手冊-V10&#xff08;中&#xff09; STM32F103ZET6(English) 一、寄存器基礎 1.1 簡介 單片機內部的控制機構。 像空氣開關控制電路一樣的原理&#xff0c;打開關閉某個開關&#xff0…

Java響應式編程

Java 響應式編程是一種基于異步數據流處理的編程范式&#xff0c;它強調數據流的聲明式構建和傳播變化的自動響應。Java 9 引入的Flow API為響應式編程提供了標準接口&#xff0c;而 Reactor 和 RxJava 等第三方庫則提供了更豐富的操作符和工具。核心概念Publisher&#xff08;…

【重學數據結構】二叉搜索樹 Binary Search Tree

目錄 二叉搜索樹的數據結構 手寫實現二叉搜索樹 樹節點定義 插入節點 源碼 流程圖 二叉樹插入步驟圖解 第一步: 插入 20 第二步: 插入 10 第三步: 插入 30 第四步: 插入 5 查找節點 源碼 場景一: 查找成功 (search for 25) 第一步: 從根節點開始 第二步:…

四、計算機組成原理——第1章:計算機系統概述

目錄 1.1計算機發展歷程 1.1.1計算機硬件的發展 1.計算機的四代變化 2.計算機元件的更新換代 1.1.2計算機軟件的發展 1.2計算機系統層次結構 1.2.1計算機系統的組成 1.2.2計算機硬件 1.馮諾依曼機基本思想 2.計算機的功能部件 (1)輸入設備 (2)輸出設備 (3)存儲器 (4)運算器 (5)…

flutter TextField 失去焦點事件

在 Flutter 中&#xff0c;處理 TextField 的失去焦點事件&#xff08;即失去焦點時觸發的操作&#xff09;通常有兩種常用方式&#xff1a;使用 FocusNode 或 onEditingComplete 回調。以下是具體實現&#xff1a; import package:flutter/material.dart;class MyTextField e…

Moonlight for ChromeOS 常見問題解決方案

Moonlight for ChromeOS 常見問題解決方案 項目基礎介紹 Moonlight for ChromeOS 是一個開源的 NVIDIA GameStream 客戶端&#xff0c;允許用戶將他們的游戲從高性能的桌面電腦流式傳輸到運行 ChromeOS 的設備上。該項目還支持 Android 和 iOS/tvOS 平臺。Moonlight for Chrome…