mormot.core.threads--TSynBackgroundThreadMethod

来源:https://www.cnblogs.com/hieroly/p/18289859
-Advertisement-
Play Games

1、Controller MVC架構中的控制層,在SpringMVC中,由 Handler 組成 負責提供訪問應用程式的行為:處理用戶的請求並調用 Model層 將其轉換為一個模型數據跳向 View層 在Spring MVC中,對於Controller的配置方式有很多種,通常可以通過介面定義或註解定 ...


mormot.core.threads--TSynBackgroundThread

在mORMot 2框架中,TSynBackgroundThreadEventTSynBackgroundThreadMethodTSynBackgroundThreadProcedureTSynBackgroundThreadProcessTSynBackgroundTimer這幾個類雖然都涉及到後臺線程的執行,但它們各自有不同的用途和設計目標。以下是對這些類之間差異的概述:

  1. TSynBackgroundThreadEvent

    • 這個類可能設計用於執行與事件相關的回調函數。它可能封裝了一個事件處理機制,允許您在後臺線程中響應特定的事件。
    • 回調函數的簽名可能包括一個事件發送者(Sender)參數,以及可能的其他參數,用於傳遞事件相關的數據。
    • 由於名稱中包含“Event”,它可能特別適用於事件驅動的場景。
  2. TSynBackgroundThreadMethod

    • 這個類設計用於執行標準的TThreadMethod類型的回調,即無參數且返回Void的過程。
    • 它提供了一種在後臺線程中執行這些回調的簡便方式,使得與Delphi標準線程庫相容的代碼可以輕鬆地與mORMot 2框架集成。
    • 由於TThreadMethod是Delphi中用於線程方法的標準類型,因此這個類可能特別適用於需要這種相容性的場景。
  3. TSynBackgroundThreadProcedure

    • 這個類可能設計用於執行簡單的無參數過程(procedure)回調,而不是一個對象方法或 TThreadMethod
    • 它與TSynBackgroundThreadMethod類似,但可能更加專註於那些不需要傳遞額外參數的過程。
    • 使用這個類可以使代碼更加簡潔,特別是當回調不需要訪問任何外部狀態或參數時。
  4. TSynBackgroundThreadProcess

    • 這個類可能是一個更通用的後臺線程處理類,它可能提供了執行周期性任務或長時間運行任務的能力。
    • 它可能封裝了線程創建、啟動、暫停、恢復和終止的邏輯,以及任務調度的機制。
    • 與其他幾個類相比,TSynBackgroundThreadProcess可能更加靈活和強大,適用於需要複雜任務調度的場景。
  5. TSynBackgroundTimer

    • 這個類專門設計用於在後臺線程中執行定時任務。
    • 它可能內部維護了一個或多個定時器,允許您安排任務在指定的時間間隔後執行。
    • TSynBackgroundTimer可能還提供了向定時任務傳遞消息或參數的能力,以及查詢任務狀態和執行結果的方法。
    • 它特別適用於需要定時執行任務的場景,如心跳檢測、定時輪詢等。

上述描述是基於對類名的一般性推斷和假設。實際上,mORMot 2框架中的這些類的具體實現和用途可能有所不同。因此,如果您正在使用mORMot 2框架,並且想要瞭解這些類的確切差異和用法,最好的做法是查閱mORMot 2的官方文檔或源代碼。這將為您提供關於這些類的詳細信息和示例代碼,幫助您更好地理解和使用它們。

TSynBackgroundThreadMethodAbstrac 定義

/// TSynBackgroundThreadAbstract 進程的狀態機狀態
TSynBackgroundThreadProcessStep = (
    flagIdle,           // 空閑狀態
    flagStarted,        // 已啟動狀態
    flagFinished,       // 已完成狀態
    flagDestroying);    // 正在銷毀狀態

/// TSynBackgroundThreadAbstract進程的狀態機狀態集合
TSynBackgroundThreadProcessSteps = set of TSynBackgroundThreadProcessStep;


/// 抽象TThread類,能夠在其自己的執行內容中運行一個方法
// - 典型用途是作為處理數據或遠程訪問的後臺線程,
// 同時UI通過迴圈運行OnIdle事件保持響應:
// 例如,查看mormot.rest.client.pas單元中TRestClientUri.OnIdle是如何處理此事件的
// - 您不應直接使用此類,而應繼承它並重寫Process方法,
// 或者使用TSynBackgroundThreadEvent/TSynBackgroundThreadMethod,
// 並提供一個更加方便的回調函數
TSynBackgroundThreadMethodAbstract = class(TSynBackgroundThreadAbstract)
protected
    fPendingProcessLock: TLightLock; // 對fPendingProcessFlag的原子訪問
    fCallerEvent: TSynEvent;         // 調用者事件
    fParam: pointer;                 // 參數指針
    fCallerThreadID: TThreadID;      // 調用者線程ID
    fBackgroundException: Exception; // 後臺線程異常
    fOnIdle: TOnIdleSynBackgroundThread; // 空閑時回調事件
    fOnBeforeProcess: TOnNotifyThread;    // 處理前通知回調
    fOnAfterProcess: TOnNotifyThread;     // 處理後通知回調
    fPendingProcessFlag: TSynBackgroundThreadProcessStep; // 待處理標誌
    procedure ExecuteLoop; override; // 重寫執行迴圈
    function OnIdleProcessNotify(var start: Int64): Int64; // 空閑處理通知,返回已用毫秒數
    function GetOnIdleBackgroundThreadActive: boolean; // 獲取OnIdle事件是否激活
    function GetPendingProcess: TSynBackgroundThreadProcessStep; // 獲取待處理狀態
    procedure SetPendingProcess(State: TSynBackgroundThreadProcessStep); // 設置待處理狀態
    // 如果獲取成功則返回flagIdle,如果已終止則返回flagDestroying
    function AcquireThread: TSynBackgroundThreadProcessStep;
    procedure WaitForFinished(start: Int64; const onmainthreadidle: TNotifyEvent); // 等待完成
    /// 當fProcessParams<>nil且fEvent被通知時,由Execute方法調用
    procedure Process; virtual; abstract; // 抽象方法,需在子類中實現
public
    /// 初始化線程
    // - 如果aOnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回
    // - 您可以定義一些回調來嵌套線程執行,例如,分配給TRestServer.BeginCurrentThread/EndCurrentThread
    constructor Create(const aOnIdle: TOnIdleSynBackgroundThread;
      const aThreadName: RawUtf8; 
      const OnBeforeExecute: TOnNotifyThread = nil;
      const OnAfterExecute: TOnNotifyThread = nil); reintroduce;
    /// 銷毀線程
    destructor Destroy; override;
    /// 在後臺線程中非同步啟動Process抽象方法
    // - 等待進程完成,同時調用OnIdle()回調
    // - 在後臺線程中引發的任何異常都將在調用者線程中轉換
    // - 如果self未設置,或者從當前正在處理的同一線程調用(以避免OnIdle()回調中的競態條件),則返回false
    // - 當後臺進程完成時返回true
    // - OpaqueParam將用於指定後臺進程線程安全的內容
    // - 此方法是線程安全的,即它將等待另一個線程已經啟動的任何進程:
    // 您可以從任何線程調用此方法,即使其主要用途是從主UI線程調用
    function RunAndWait(OpaqueParam: pointer): boolean;
    /// 設置一個回調事件,在遠程阻塞過程期間迴圈執行,
    // 例如,在長時間請求期間刷新UI
    // - 您可以為此屬性分配一個回調,例如調用Application.ProcessMessages,
    // 以在後臺線程中執行遠程請求,但讓UI仍然具有響應性:
    // mORMotUILogin.pas中的TLoginForm.OnIdleProcess和OnIdleProcessForm方法將符合此屬性的預期
    // - 如果OnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回
    property OnIdle: TOnIdleSynBackgroundThread   read fOnIdle write fOnIdle;
    /// 如果後臺線程處於活動狀態,並且在處理過程中調用了OnIdle事件,則為TRUE
    // - 例如,用於確保沒有來自用戶界面消息的重新進入
    property OnIdleBackgroundThreadActive: boolean read GetOnIdleBackgroundThreadActive;
    /// 在Execute中每次處理之前觸發的可選回調事件
    property OnBeforeProcess: TOnNotifyThread   read fOnBeforeProcess write fOnBeforeProcess;
    /// 在Execute中每次處理之後觸發的可選回調事件
    property OnAfterProcess: TOnNotifyThread    read fOnAfterProcess write fOnAfterProcess;
end;

TSynBackgroundThreadEvent,TSynBackgroundThreadMethod,TSynBackgroundThreadProcedure,TSynBackgroundThreadProcess

TSynBackgroundThreadEvent 定義

/// 由 TSynBackgroundThreadEvent 調用的後臺進程方法
// - 當執行Process虛擬方法時,將提供RunAndWait()方法中指定的OpaqueParam參數
TOnProcessSynBackgroundThread = procedure(Sender: TSynBackgroundThreadEvent;
    ProcessOpaqueParam: pointer) of object;

/// 允許後臺線程處理方法回調
TSynBackgroundThreadEvent = class(TSynBackgroundThreadMethodAbstract)
protected
    fOnProcess: TOnProcessSynBackgroundThread; // 回調事件
    /// 僅調用OnProcess處理程式
    procedure Process; override; // 重寫Process方法
public
    /// 初始化線程
    // - 如果aOnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回
    constructor Create(const aOnProcess: TOnProcessSynBackgroundThread;
      const aOnIdle: TOnIdleSynBackgroundThread;
      const aThreadName: RawUtf8); reintroduce; // 重引入構造函數
    /// 提供一個方法處理程式,在後臺線程中執行
    // - 由RunAndWait()方法觸發 - 該方法將等待直到完成
    // - 這裡將提供RunAndWait()方法中指定的OpaqueParam
    property OnProcess: TOnProcessSynBackgroundThread
      read fOnProcess write fOnProcess; // OnProcess屬性,用於訪問fOnProcess欄位
end;

TSynBackgroundThreadMethod 定義

/// 允許後臺線程處理可變的TThreadMethod回調
TSynBackgroundThreadMethod = class(TSynBackgroundThreadMethodAbstract)
protected
    /// 僅調用RunAndWait()方法中提供的TThreadMethod
    procedure Process; override; // 重寫Process方法
public
    /// 運行一次提供的TThreadMethod回調
    // - 使用此方法,而不是繼承的RunAndWait()
    procedure RunAndWait(Method: TThreadMethod); reintroduce; // 重引入RunAndWait方法
end;

TSynBackgroundThreadProcedure 定義

/// 由 TSynBackgroundThreadProcedure 調用的後臺進程過程
// - 當執行Process虛擬方法時,將提供RunAndWait()方法中指定的OpaqueParam參數
TOnProcessSynBackgroundThreadProc = procedure(ProcessOpaqueParam: pointer);

/// 允許後臺線程處理過程回調
TSynBackgroundThreadProcedure = class(TSynBackgroundThreadMethodAbstract)
protected
    fOnProcess: TOnProcessSynBackgroundThreadProc; // 回調過程
    /// 僅調用OnProcess處理程式
    procedure Process; override; // 重寫Process方法
public
    /// 初始化線程
    // - 如果aOnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回
    constructor Create(aOnProcess: TOnProcessSynBackgroundThreadProc;
      const aOnIdle: TOnIdleSynBackgroundThread;
      const aThreadName: RawUtf8); reintroduce; // 重引入構造函數
    
    /// 提供一個過程處理程式,在後臺線程中執行
    // - 由RunAndWait()方法觸發 - 該方法將等待直到完成
    // - 這裡將提供RunAndWait()方法中指定的OpaqueParam
    property OnProcess: TOnProcessSynBackgroundThreadProc 
      read fOnProcess write fOnProcess; // OnProcess屬性,用於訪問fOnProcess欄位
end;

TSynBackgroundThreadProcess 定義

type
  // TSynBackgroundThreadProcess 類聲明(稍後定義)
  TSynBackgroundThreadProcess = class;

  /// 由 TSynBackgroundThreadProcess 定期執行的事件回調
  TOnSynBackgroundThreadProcess = procedure(Sender: TSynBackgroundThreadProcess) of object;

  /// 能夠以給定周期運行方法的 TThread 類
  TSynBackgroundThreadProcess = class(TSynBackgroundThreadAbstract)
  protected
    fOnProcess: TOnSynBackgroundThreadProcess; // 定期執行的方法回調
    fOnException: TNotifyEvent; // 當 OnProcess 引發異常時執行的事件回調
    fOnProcessMS: cardinal; // 定期執行任務的時間間隔(毫秒)
    fStats: TSynMonitor; // 處理統計信息
    procedure ExecuteLoop; override; // 重寫執行迴圈
  public
    /// 初始化線程以進行周期性任務處理
    // - 當 ProcessEvent.SetEvent 被調用或自上次處理以來過去了 aOnProcessMS 毫秒時,將調用 aOnProcess
    // - 如果 aOnProcessMS 為 0,則等待直到 ProcessEvent.SetEvent 被調用
    // - 您可以定義一些回調來嵌套線程執行,例如,分配給 TRestServer.BeginCurrentThread/EndCurrentThread
    constructor Create(const aThreadName: RawUtf8;
        const aOnProcess: TOnSynBackgroundThreadProcess;
        aOnProcessMS: cardinal; 
        const aOnBeforeExecute: TOnNotifyThread = nil;
        const aOnAfterExecute: TOnNotifyThread = nil;
        aStats: TSynMonitorClass = nil;
        CreateSuspended: boolean = false); reintroduce; virtual;
    
    /// 終結線程並等待其結束
    destructor Destroy; override;
    
    /// 訪問周期性任務的實現事件
    property OnProcess: TOnSynBackgroundThreadProcess
      read fOnProcess;
    
    /// 當 OnProcess 引發異常時執行的事件回調
    // - 提供的 Sender 參數是引發的異常實例
    property OnException: TNotifyEvent
      read fOnException write fOnException;
  
  published
    
    /// 訪問周期性任務處理的延遲時間(毫秒)
    property OnProcessMS: cardinal  read fOnProcessMS write fOnProcessMS;
    
    /// 處理統計信息
    // - 如果在類構造函數中 aStats 為 nil,則可能為 nil
    property Stats: TSynMonitor   read fStats;
  end;

TSynBackgroundThreadEvent 常式代碼

uses
  SysUtils, Classes, // 引入必要的單元
  mormot.core.threads;

type
  TMyProcessEvent = procedure(Sender: TObject; Param: Pointer) of object;

var
  MyProcessEvent: TMyProcessEvent;

procedure MyBackgroundProcess(Sender: TObject; ProcessOpaqueParam: Pointer);
begin
  // 這裡是後臺處理的代碼
  WriteLn('Background process running with param: ', Pointer(ProcessOpaqueParam)^);
  // 假設我們傳遞了一個Integer指針作為OpaqueParam
  Integer(ProcessOpaqueParam)^ := Integer(ProcessOpaqueParam)^ + 1;
end;

procedure InitializeAndRunBackgroundThreadEvent;
var
  BGThread: TSynBackgroundThreadEvent;
  Param: PInteger;
begin
  New(Param);
  Param^ := 10; // 初始化參數

  MyProcessEvent := MyBackgroundProcess;

  // 創建並啟動後臺線程事件
  BGThread := TSynBackgroundThreadEvent.Create(
    MyProcessEvent, // 傳遞我們的處理過程
    nil, // OnIdle回調,這裡不使用
    'MyBackgroundThreadEventDemo'
  );
  try
    // 運行後臺線程並等待完成
    BGThread.RunAndWait(Param);
    WriteLn('Background process finished. New param value: ', Param^);
  finally
    BGThread.Free; // 銷毀線程對象
    Dispose(Param); // 釋放參數記憶體
  end;
end;

// 在程式的某個地方調用InitializeAndRunBackgroundThreadEvent

TSynBackgroundThreadMethod 常式代碼

uses
  SysUtils, Classes,
  mormot.core.threads;

procedure MyThreadMethod(Thread: TThread);
begin
  // 這裡是線程方法的代碼
  WriteLn('Thread method running in background');
  // 模擬一些耗時操作
  Sleep(1000);
end;

procedure RunBackgroundThreadMethod;
var
  BGThread: TSynBackgroundThreadMethod;
begin
  // 創建後臺線程方法對象
  BGThread := TSynBackgroundThreadMethod.Create(nil, nil, 'MyBackgroundThreadMethodDemo');
  try
    // 註意:這裡我們重寫了RunAndWait方法,所以直接傳遞TThreadMethod
    BGThread.RunAndWait(MyThreadMethod);
  finally
    BGThread.Free; // 銷毀線程對象
  end;
end;

// 在程式的某個地方調用RunBackgroundThreadMethod

註意:上面的 TSynBackgroundThreadMethod示例中,我假設了 RunAndWait方法被重寫以接受 TThreadMethod作為參數,但根據原始定義,這並不是直接支持的。通常,您會在 Process方法內部調用傳入的 TThreadMethod。為了保持示例簡單,我展示瞭如何可能使用它,但在實際應用中,您可能需要在 Process方法內部處理這一點。

TSynBackgroundThreadProcedure 常式代碼

uses
  SysUtils, Classes,
  mormot.core.threads;

procedure MyBackgroundProcedure(ProcessOpaqueParam: Pointer);
begin
  // 這裡是後臺過程的代碼
  WriteLn('Background procedure running with param: ', Pointer(ProcessOpaqueParam)^);
  // 假設我們傳遞了一個字元串指針作為OpaqueParam
  WriteLn('String param: ', PString(ProcessOpaqueParam)^);
end;

procedure InitializeAndRunBackgroundThreadProcedure;
var
  BGThread: TSynBackgroundThreadProcedure;
  Param: PString;
begin
  New(Param);
  Param^ := 'Hello, Background!';

  // 創建並啟動後臺線程過程
  BGThread := TSynBackgroundThreadProcedure.Create(
    MyBackgroundProcedure, // 傳遞我們的處理過程
    nil, // OnIdle回調,這裡不使用
    'MyBackgroundThreadProcedureDemo'
  );
  try
    // 運行後臺線程並等待完成
    BGThread.RunAndWait(Param);
  finally
    BGThread.Free; // 銷毀線程對象
    Dispose(Param); // 釋放參數記憶體
  end;
end;

// 在程式的某個地方調用InitializeAndRunBackgroundThreadProcedure

TSynBackgroundThreadProcess 常式代碼

uses
  SysUtils, Classes, // 引入SysUtils和Classes單元以使用WriteLn和TThread等
  mormot.core.threads;

procedure MyProcessMethod(Sender: TSynBackgroundThreadProcess);
begin
  WriteLn('Process method called in background thread.');
  // 在這裡執行您的後臺處理邏輯
end;

var
  BGThread: TSynBackgroundThreadProcess;

begin
  try
    // 創建TSynBackgroundThreadProcess實例
    BGThread := TSynBackgroundThreadProcess.Create(
      'MyBackgroundThread', // 線程名稱
      MyProcessMethod, // 周期性執行的方法
      1000, // 周期時間,單位為毫秒
      nil, // OnBeforeExecute回調,這裡不使用
      nil  // OnAfterExecute回調,這裡不使用
      // aStats和其他參數根據需要進行設置
    );
    try
      // 啟動線程(註意:在TSynBackgroundThreadProcess的構造函數中,
      // 如果CreateSuspended參數為false,則線程將自動啟動)
      // 在這個例子中,我們假設CreateSuspended預設為false

      // 等待一段時間以觀察後臺線程的行為
      // 註意:在實際應用中,您可能不需要這樣做,因為主線程可能會繼續執行其他任務
      Sleep(5000); // 等待5秒

    finally
      // 銷毀線程對象(註意:在析構函數中,線程將嘗試優雅地終止)
      BGThread.Free;
      // 等待線程真正結束(可選,但在這個例子中我們依賴析構函數的行為)
    end;
  except
    on E: Exception do
      WriteLn('Error: ' + E.Message);
  end;
  WriteLn('Program ended.');
end.

註意:在上面的示例中,我假設TSynBackgroundThreadProcess的構造函數有一個CreateSuspended參數(這在標準的TThread構造函數中是存在的),但根據您提供的類定義,這個參數實際上並沒有在TSynBackgroundThreadProcess的構造函數中明確列出。如果TSynBackgroundThreadProcess是自動啟動線程的,那麼您可能不需要顯式調用任何啟動方法。

TSynBackgroundTimer 常式代碼

uses
  SysUtils, // 引入SysUtils單元以使用WriteLn
  mormot.core.threads;

procedure MyTimerProcess(Sender: TSynBackgroundTimer; const Msg: RawUtf8);
begin
  WriteLn('Timer process called in background thread. Message: ' + Msg);
  // 在這裡執行您的定時任務邏輯
end;

var
  Timer: TSynBackgroundTimer;

begin
  try
    // 創建TSynBackgroundTimer實例
    Timer := TSynBackgroundTimer.Create(
      'MyBackgroundTimer' // 線程名稱
      // 其他參數根據需要進行設置,這裡省略了OnBeforeExecute、OnAfterExecute、aStats和aLogClass
    );
    try
      // 啟用一個周期性任務,每2秒執行一次
      Timer.Enable(@MyTimerProcess, 2);

      // 向任務隊列添加消息,並請求立即執行(儘管在這個上下文中,立即執行可能不會立即發生)
      Timer.EnQueue(@MyTimerProcess, 'Hello from background timer!', true);

      // 等待一段時間以觀察後臺定時器的行為
      // 註意:在實際應用中,您可能不需要這樣做,因為主線程可能會繼續執行其他任務
      Sleep(10000); // 等待10秒

      // 禁用周期性任務(在這個示例中我們不會禁用它,但展示瞭如何禁用)
      // Timer.Disable(@MyTimerProcess);

    finally
      // 銷毀TSynBackgroundTimer實例(註意:在實際應用中,您可能希望等待所有後臺任務完成後再銷毀定時器)
      // 但在這個簡單示例中,我們立即銷毀它
      Timer.Free;
      // 由於我們立即銷毀了定時器,並且主線程繼續執行(儘管在這個示例中被Sleep阻塞了),
      // 因此後臺線程可能沒有機會執行更多的回調。
      // 在實際應用中,您應該確保在銷毀定時器之前給後臺線程足夠的時間來完成其工作。
    end;
  except
    on E: Exception do
      WriteLn('Error: ' + E.Message);
  end;
  WriteLn('Program ended.');
end.

在上面的TSynBackgroundTimer示例中,我展示瞭如何創建定時器、啟用周期性任務、向任務隊列添加消息,並等待一段時間以觀察定時器的行為。請註意,由於我們調用了Sleep並且立即銷毀了定時器,因此後臺線程可能沒有機會執行更多的回調。在實際應用中,您應該確保在銷毀定時器之前給後臺線程足夠的時間來完成其工作,或者調用Timer.WaitUntilNotProcessing(如果該類提供了這樣的方法)來等待所有後臺任務完成。然而,根據提供的類定義,TSynBackgroundTimer並沒有直接提供WaitUntilNotProcessing方法,所以您可能需要實現自己的同步機制來達到這個目的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 動態表單系統:利用 Spring Boot 和 MyBatis 實現後端服務 在現代企業應用中,表單是數據收集和處理的核心部分。然而,傳統的表單系統難以適應快速變化的需求。為瞭解決這個問題,我們可以使用動態表單系統,它可以根據業務需求靈活地調整表單結構。本文將介紹如何使用 Spring Boo ...
  • 本文探討了Node.js事件迴圈中的timers階段,分析了定時器的管理和執行過程。通過源碼解析,揭示了定時器超時檢查、回調執行以及定時器類型(setTimeout與setInterval)的內部實現機制。文章旨在幫助讀者理解Node.js中定時器的工作原理及其在事件驅動編程中的重要性。 ...
  • 摘要:本文詳細介紹了Nuxt3框架中的五個webpack鉤子函數:webpack:configResolved用於在webpack配置解析後讀取和修改配置;webpack:compile在編譯開始前調用,可修改編譯選項;webpack:compiled在編譯完成後調用,可處理編譯結果;webpack... ...
  • ‍ 寫在開頭 點贊 + 收藏 學會 前言: 最近接到了一個需求很有意思,類似於我們經常在逛購物平臺中,選擇一個物品分享給好友,然後好友複製這段文本打開相對應的平臺以後,就可以彈出鏈接上的物品。實現過程也比較有意思,特來分享一下實現思路。 一. 效果預覽 當我在別的界面複製了內 ...
  • 本節課,我們主要講解了在Python類的繼承中子類如何進行初始化、調用父類的屬性和方法,同時講解了模擬串口感測器和主機類的具體實現,並使用xcom串口助手與兩個類進行串口通信使用。 ...
  • # Maven簡介 Maven的本質是一個項目管理工具,將項目開發和管理過程抽象成一個項目對象模型(POM)) 這玩意兒是使用Java開發的,所以採用的就是Java的思想:面向對象 POM (Project Object Model):項目對象模型 Maven的作用: 項目構建:提供標準的、跨平臺的 ...
  • 生成全局唯一 ID 全局唯一 ID 需要滿足以下要求: 唯一性:在分散式環境中,要全局唯一 高可用:在高併發情況下保證可用性 高性能:在高併發情況下生成 ID 的速度必須要快,不能花費太長時間 遞增性:要確保整體遞增的,以便於資料庫創建索引 安全性:ID 的規律性不能太明顯,以免信息泄露 從上面的要 ...
  • 1 註冊中心 1.1 為什麼要用註冊中心 微服務之間會相互調用,假如有兩個服務orderService和userService,orderService會調用userService獲取當前訂單相關的用戶信息,且userService部署了多個實例: 大家思考幾個問題: order-service在發 ...
一周排行
    -Advertisement-
    Play Games
  • 通過WPF的按鈕、文本輸入框實現了一個簡單的SpinBox數字輸入用戶組件並可以通過數據綁定數值和步長。本文中介紹了通過Xaml代碼實現自定義組件的佈局,依賴屬性的定義和使用等知識點。 ...
  • 以前,我看到一個朋友在對一個系統做初始化的時候,通過一組魔幻般的按鍵,調出來一個隱藏的系統設置界面,這個界面在常規的菜單或者工具欄是看不到的,因為它是一個後臺設置的關鍵界面,不公開,同時避免常規用戶的誤操作,它是作為一個超級管理員的入口功能,這個是很不錯的思路。其實Winform做這樣的處理也是很容... ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他的程式每次關閉時就會自動崩潰,一直找不到原因讓我幫忙看一下怎麼回事,這位朋友應該是第二次找我了,分析了下 dump 還是挺經典的,拿出來給大家分享一下吧。 二:WinDbg 分析 1. 為什麼會崩潰 找崩潰原因比較簡單,用 !analyze -v 命 ...
  • 在一些報表模塊中,需要我們根據用戶操作的名稱,來動態根據人員姓名,更新報表的簽名圖片,也就是電子手寫簽名效果,本篇隨筆介紹一下使用FastReport報表動態更新人員簽名圖片。 ...
  • 最新內容優先發佈於個人博客:小虎技術分享站,隨後逐步搬運到博客園。 創作不易,如果覺得有用請在Github上為博主點亮一顆小星星吧! 博主開始學習編程於11年前,年少時還只會使用cin 和cout ,給單片機點點燈。那時候,類似async/await 和future/promise 模型的認知還不是 ...
  • 之前在阿裡雲ECS 99元/年的活動實例上搭建了一個測試用的MINIO服務,以前都是直接當基礎設施來使用的,這次準備自己學一下S3相容API相關的對象存儲開發,因此有了這個小工具。目前僅包含上傳功能,後續計劃開發一個類似圖床的對象存儲應用。 ...
  • 目錄簡介快速入門安裝 NuGet 包實體類User資料庫類DbFactory增刪改查InsertSelectUpdateDelete總結 簡介 NPoco 是 PetaPoco 的一個分支,具有一些額外的功能,截至現在 github 星數 839。NPoco 中文資料沒多少,我是被博客園群友推薦的, ...
  • 前言 前面使用 Admin.Core 的代碼生成器生成了通用代碼生成器的基礎模塊 分組,模板,項目,項目模型,項目欄位的基礎功能,本篇繼續完善,實現最核心的模板生成功能,並提供生成預覽及代碼文件壓縮下載 準備 首先清楚幾個模塊的關係,如何使用,簡單畫一個流程圖 前面完成了基礎的模板組,模板管理,項目 ...
  • 假設需要實現一個圖標和文本結合的按鈕 ,普通做法是 直接重寫該按鈕的模板; 如果想作為通用的呢? 兩種做法: 附加屬性 自定義控制項 推薦使用附加屬性的形式 第一種:附加屬性 創建Button的附加屬性 ButtonExtensions 1 public static class ButtonExte ...
  • 在C#中,委托是一種引用類型的數據類型,允許我們封裝方法的引用。通過使用委托,我們可以將方法作為參數傳遞給其他方法,或者將多個方法組合在一起,從而實現更靈活的編程模式。委托類似於函數指針,但提供了類型安全和垃圾回收等現代語言特性。 基本概念 定義委托 定義委托需要指定它所代表的方法的原型,包括返回類 ...