首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

C# 開發多執行緒元件實戰:非同步計算與事件通知模式

     編輯:C# 入門

專案架構

  • Calculations (Windows Forms 專案):主視窗 frmCalculations,包含輸入框、4 個運算按鈕、結果顯示標籤。
  • Calculator (元件類別):封裝多執行緒計算邏輯,透過事件回報進度與結果。

Calculator 元件核心代碼

using System;
using System.Threading;

public class Calculator
{
    // 公共欄位:接收 UI 傳入參數
    public int varAddTwo;
    public int varFact1;
    public int varFact2;
    public int varLoopValue;
    public double varTotalCalculations = 0;

    // 事件委派定義
    public delegate void FactorialCompleteHandler(double Factorial, double TotalCalculations);
    public delegate void AddTwoCompleteHandler(int Result, double TotalCalculations);
    public delegate void LoopCompleteHandler(double TotalCalculations, int Counter);

    // 事件
    public event FactorialCompleteHandler FactorialComplete;
    public event FactorialCompleteHandler FactorialMinusOneComplete;
    public event AddTwoCompleteHandler AddTwoComplete;
    public event LoopCompleteHandler LoopComplete;

    // 階乘計算 (varFact1!)
    public void Factorial()
    {
        double result = 1, totalNow = 0;
        for (int i = 1; i <= varFact1; i++)
        {
            result *= i;
            varTotalCalculations += 1;
            totalNow = varTotalCalculations;
        }
        FactorialComplete?.Invoke(result, totalNow);
    }

    // 階乘計算 (varFact2-1)!
    public void FactorialMinusOne()
    {
        double result = 1, totalNow = 0;
        for (int i = 1; i <= varFact2 - 1; i++)
        {
            result *= i;
            varTotalCalculations += 1;
            totalNow = varTotalCalculations;
        }
        FactorialMinusOneComplete?.Invoke(result, totalNow);
    }

    // 簡單加法
    public void AddTwo()
    {
        int result = varAddTwo + 2;
        varTotalCalculations += 1;
        AddTwoComplete?.Invoke(result, varTotalCalculations);
    }

    // 巢狀迴圈模擬高負載
    public void RunALoop()
    {
        double totalNow = 0;
        for (int x = 1; x <= varLoopValue; x++)
            for (int y = 1; y <= 500; y++)
            {
                varTotalCalculations += 1;
                totalNow = varTotalCalculations;
            }
        LoopComplete?.Invoke(totalNow, varLoopValue);
    }
}

UI 端串接與執行緒啟動

public partial class frmCalculations : Form
{
    private Calculator calc = new Calculator();

    public frmCalculations()
    {
        InitializeComponent();
        // 訂閱事件
        calc.FactorialComplete += (r, t) => { lblFactorial1.Text = r.ToString(); lblTotal.Text = t.ToString(); btnFactorial1.Enabled = true; };
        calc.FactorialMinusOneComplete += (r, t) => { lblFactorial2.Text = r.ToString(); lblTotal.Text = t.ToString(); btnFactorial2.Enabled = true; };
        calc.AddTwoComplete += (r, t) => { lblAddTwo.Text = r.ToString(); lblTotal.Text = t.ToString(); btnAddTwo.Enabled = true; };
        calc.LoopComplete += (t, c) => { lblRunLoops.Text = c.ToString(); lblTotal.Text = t.ToString(); btnRunLoops.Enabled = true; };
    }

    private void btnFactorial1_Click(object sender, EventArgs e)
    {
        calc.varFact1 = int.Parse(txtValue.Text);
        btnFactorial1.Enabled = false;
        ThreadPool.QueueUserWorkItem(_ => calc.Factorial()); // 執行緒池啟動
    }
    // 其他按鈕同理...
}

關鍵設計重點

  • 元件不直接操作 UI,透過事件解耦。
  • 參數透過公共欄位傳遞(簡單示範),生產環境建議用 ThreadStart 包裝或 Task 傳遞強型別參數。
  • 使用 ThreadPool.QueueUserWorkItem 避免手動管理執行緒生命週期。
  • 事件呼叫使用 ?.Invoke 防止無訂閱者時擲回 NullReferenceException。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved