MultithreadingScaffold 1.2.0

dotnet add package MultithreadingScaffold --version 1.2.0
                    
NuGet\Install-Package MultithreadingScaffold -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MultithreadingScaffold" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MultithreadingScaffold" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="MultithreadingScaffold" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MultithreadingScaffold --version 1.2.0
                    
#r "nuget: MultithreadingScaffold, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MultithreadingScaffold@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MultithreadingScaffold&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=MultithreadingScaffold&version=1.2.0
                    
Install as a Cake Tool

MultithreadingScaffold

NuGet License: MIT

A lightweight .NET Standard 2.0 library that provides a scaffolding framework for quickly creating multi-threaded work code with minimal boilerplate.

多线程工作脚手架,用于快速创建多线程工作代码的轻量级框架。

Features | 主要特性

  • Two Operation Modes | 双模式运行

    • Normal Mode: Dynamic thread creation as work becomes available
    • Plan Mode: Pre-sliced workload with fixed thread pool for better performance
    • 普通模式:根据工作量动态创建线程
    • 计划模式:预先切分任务,使用固定线程池,减少上下文切换,提升性能
  • Simple API | 简洁的 API

    • Minimal configuration required
    • Delegate-based worker pattern
    • 最少配置即可使用
    • 基于委托的工作模式
  • Resource Management | 资源管理

    • Implements IDisposable for proper cleanup
    • Automatic thread lifecycle management
    • 实现 IDisposable 接口,支持资源清理
    • 自动管理线程生命周期
  • Advanced Features | 高级特性

    • TTL (Time-To-Live) support for automatic timeout
    • Configurable thread limits and sleep intervals
    • Exception handling with optional logging
    • 支持 TTL 超时自动停止
    • 可配置线程数量和睡眠间隔
    • 异常处理与可选日志输出

Installation | 安装

dotnet add package MultithreadingScaffold

Or via NuGet Package Manager:

Install-Package MultithreadingScaffold

Quick Start | 快速开始

Normal Mode | 普通模式

using MultithreadingScaffold;

var data = new string[] { "Task A", "Task B", "Task C", "Task D", "Task E" };

using (var scaffold = new MTScaffold())
{
    scaffold.Workload = data.Length;
    scaffold.Worker = (index) =>
    {
        Console.WriteLine($"Processing: {data[index]} on Thread {Thread.CurrentThread.ManagedThreadId}");
        Thread.Sleep(100); // Simulate work
    };
    scaffold.Final = () =>
    {
        Console.WriteLine("All tasks completed!");
    };

    scaffold.Start(); // Blocks current thread until completion
}

Plan Mode | 计划模式

using MultithreadingScaffold;

var data = Enumerable.Range(0, 1000).ToArray();

using (var scaffold = new MTScaffold())
{
    scaffold.IsPlanningMode = true;  // Enable Plan Mode
    scaffold.ThreadLimit = 4;         // Use 4 threads
    scaffold.Workload = data.Length;

    scaffold.Worker = (index) =>
    {
        // Process data[index]
        var result = data[index] * 2;
        Console.WriteLine($"Processed {index}: {result}");
    };

    scaffold.Final = () =>
    {
        Console.WriteLine("Batch processing completed!");
    };

    scaffold.Start();
}

Non-Blocking Mode | 非阻塞模式

using MultithreadingScaffold;

var scaffold = new MTScaffold();
scaffold.InNewThread = true;  // Run in background thread
scaffold.Workload = 100;
scaffold.Worker = (i) => { /* Do work */ };
scaffold.Final = () => { Console.WriteLine("Done!"); };

scaffold.Start(); // Returns immediately

// Check if still running
while (scaffold.IsRunning)
{
    Console.WriteLine("Working...");
    Thread.Sleep(500);
}

scaffold.Dispose();

Configuration Parameters | 配置参数

Required Parameters | 必需参数

Parameter Type Description
Workload int Total number of work items to process<br/>工作总量,表示需要处理的任务数量
Worker ThreadWorker Delegate that processes each work item<br/>工作委托,处理每个任务项 void Worker(long index)

Optional Parameters | 可选参数

Parameter Type Default Description
Final ThreadFinal null Callback invoked after all work completes<br/>所有任务完成后的回调函数
IsPlanningMode bool false Enable Plan Mode for better performance with large workloads<br/>启用计划模式,适合大批量任务,性能更优
InNewThread bool false Run scheduler in background thread (non-blocking)<br/>在后台线程运行调度器(非阻塞)
ThreadLimit int CPU cores Maximum concurrent threads (0 = auto-detect)<br/>最大并发线程数(0 表示自动检测 CPU 核心数)
SleepTime int 10 Thread spawn interval in milliseconds<br/>线程启动间隔(毫秒)
TTL int -1 Time-to-live in seconds (-1 = disabled)<br/>存活时间(秒),-1 表示禁用
WriteConsole bool false Enable debug logging to console<br/>启用控制台调试日志

Read-Only Properties | 只读属性

Property Type Description
IsRunning bool Indicates if threads are currently active<br/>指示是否有线程正在运行
Counter long Number of completed work items<br/>已完成的任务数量

Usage Examples | 使用示例

Example 1: Parallel Data Processing | 并行数据处理

var numbers = Enumerable.Range(1, 1000).ToArray();
var results = new int[numbers.Length];

using (var scaffold = new MTScaffold())
{
    scaffold.IsPlanningMode = true;
    scaffold.ThreadLimit = Environment.ProcessorCount;
    scaffold.Workload = numbers.Length;

    scaffold.Worker = (i) =>
    {
        results[i] = numbers[i] * numbers[i]; // Square each number
    };

    scaffold.Start();
}

Console.WriteLine($"Processed {results.Length} items");

Example 2: Web Scraping with Timeout | 带超时的网页抓取

var urls = new[] { "url1", "url2", "url3", /* ... */ };

using (var scaffold = new MTScaffold())
{
    scaffold.Workload = urls.Length;
    scaffold.ThreadLimit = 5;
    scaffold.TTL = 30; // 30 seconds timeout
    scaffold.WriteConsole = true;

    scaffold.Worker = (i) =>
    {
        try
        {
            var content = DownloadUrl(urls[i]);
            ProcessContent(content);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error processing {urls[i]}: {ex.Message}");
        }
    };

    scaffold.Final = () =>
    {
        Console.WriteLine("Scraping completed or timed out");
    };

    scaffold.Start();
}

Example 3: Background Task Processing | 后台任务处理

var taskQueue = GetTaskQueue(); // Returns List<Task>

var scaffold = new MTScaffold
{
    InNewThread = true,
    IsPlanningMode = true,
    ThreadLimit = 8,
    Workload = taskQueue.Count,
    Worker = (i) =>
    {
        ProcessTask(taskQueue[(int)i]);
    },
    Final = () =>
    {
        Console.WriteLine("Background processing finished");
        NotifyCompletion();
    }
};

scaffold.Start(); // Non-blocking

// Continue with other work
DoOtherWork();

// Later, check status
if (scaffold.IsRunning)
{
    Console.WriteLine($"Progress: {scaffold.Counter}/{scaffold.Workload}");
}

// Clean up when done
scaffold.Dispose();

Important Notes | 注意事项

Thread Safety | 线程安全

  • The Worker delegate may be called concurrently from multiple threads
  • Ensure your worker code is thread-safe or uses appropriate synchronization
  • Avoid shared mutable state without proper locking
  • The MTScaffold instance itself is thread-safe for concurrent worker execution

工作委托可能被多个线程并发调用,请确保代码线程安全或使用适当的同步机制。避免在没有适当锁定的情况下使用共享可变状态。MTScaffold 实例本身对于并发工作执行是线程安全的。

Resource Management | 资源管理

  • Always use using statement or call Dispose() when done
  • Disposal cancels TTL tasks and interrupts running threads
  • Do not reuse a disposed MTScaffold instance
  • Cannot call Start() multiple times - create a new instance for each run

始终使用 using 语句或调用 Dispose() 方法。释放操作会取消 TTL 任务并中断运行中的线程。不要重用已释放的实例。不能多次调用 Start() - 每次运行需要创建新实例。

Performance Considerations | 性能考虑

  • Normal Mode: Best for unpredictable workloads or when tasks complete at different rates
  • Plan Mode: Best for uniform workloads with predictable execution time (now with dynamic thread creation)
  • Adjust ThreadLimit based on workload type (CPU-bound vs I/O-bound)
  • Lower SleepTime for faster thread spawning, but may increase CPU usage
  • Plan Mode now creates threads dynamically, combining pre-allocation benefits with flexibility

普通模式:适合不可预测的工作负载或任务完成速度不同的场景 计划模式:适合统一的工作负载和可预测的执行时间(现已支持动态线程创建) 根据工作负载类型(CPU 密集型 vs I/O 密集型)调整 ThreadLimit 降低 SleepTime 可加快线程启动,但可能增加 CPU 使用率 计划模式现在动态创建线程,结合了预分配的优势和灵活性

Exception Handling | 异常处理

  • Exceptions in Worker are caught and logged (if WriteConsole = true)
  • Unhandled exceptions will not crash the entire scaffold
  • Implement try-catch in your worker for custom error handling
  • Failed tasks do not prevent other tasks from executing

工作委托中的异常会被捕获并记录(如果 WriteConsole = true 未处理的异常不会导致整个脚手架崩溃 在工作委托中实现 try-catch 以进行自定义错误处理 失败的任务不会阻止其他任务执行

TTL Behavior | TTL 行为

  • When TTL expires, all threads are interrupted via Thread.Interrupt()
  • The Final callback is still invoked after TTL timeout
  • Ensure your worker code handles ThreadInterruptedException gracefully
  • TTL is measured accurately using Stopwatch (not affected by system time changes)

TTL 超时后,所有线程通过 Thread.Interrupt() 中断 TTL 超时后仍会调用 Final 回调 确保工作代码能够优雅地处理 ThreadInterruptedException TTL 使用 Stopwatch 精确测量(不受系统时间变化影响)

Reusability | 可重用性

  • One-time use: Each MTScaffold instance can only be started once
  • Calling Start() multiple times throws InvalidOperationException
  • Create a new instance if you need to run the same workload again

一次性使用:每个 MTScaffold 实例只能启动一次 多次调用 Start() 会抛出 InvalidOperationException 如需再次运行相同工作负载,请创建新实例

Choosing Between Modes | 模式选择

Use Normal Mode When | 使用普通模式的场景

  • Work items have unpredictable execution times
  • You want dynamic thread creation based on availability
  • Workload is small to medium sized
  • Tasks may fail and you want other tasks to continue

任务执行时间不可预测 希望根据可用性动态创建线程 工作负载为小到中等规模 任务可能失败,希望其他任务继续执行

Use Plan Mode When | 使用计划模式的场景

  • Work items have similar execution times
  • You have a large batch of uniform tasks
  • You want to minimize thread context switching
  • You need predictable thread count

任务执行时间相似 有大批量统一的任务 希望最小化线程上下文切换 需要可预测的线程数量

Version History | 版本历史

v1.2.0 (Latest)

Critical Bug Fixes:

  • Fixed critical TTL time calculation bug (now uses Stopwatch instead of DateTime.Now.Second)
  • Fixed Plan Mode deadlock issue with PlanTaskCounter

Improvements:

  • Improved thread synchronization to reduce CPU waste
  • Enhanced exception handling to catch all exceptions
  • Implemented IDisposable for proper resource cleanup
  • Added IsRunning property for monitoring scaffold state
  • Optimized default SleepTime from 100ms to 10ms
  • Enhanced parameter validation with detailed error messages
  • Fixed race condition in ThreadCount increment timing
  • Optimized memory allocation in GetPlanArr with capacity pre-allocation

Plan Mode Enhancements:

  • Changed to dynamic thread creation (threads created on-demand, not all at once)
  • Improved thread-safety with proper locking for shared resources
  • Better resource management with tracked TTL tasks

API Changes:

  • Added protection against multiple Start() calls
  • Added IsRunning read-only property
  • Improved disposal pattern with proper cleanup sequencing

v1.1.1

  • Added Plan Mode support
  • Improved thread management

v1.0.x

  • Initial release with Normal Mode

Requirements | 系统要求

  • .NET Standard 2.0 or higher
  • Compatible with .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+

License | 许可证

MIT License - see LICENSE for details

Contributing | 贡献

Contributions are welcome! Please feel free to submit issues or pull requests.

欢迎贡献!请随时提交问题或拉取请求。

Repository | 代码仓库

https://github.com/ChaoShengze/MultithreadingScaffold

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 83 1/23/2026
1.1.1 220 3/22/2024
1.1.0 168 3/21/2024
1.0.1 743 6/22/2020
1.0.0 639 4/27/2020

Version 1.2.0:
- Fixed critical TTL time calculation bug (now uses Stopwatch instead of DateTime.Now.Second)
- Fixed Plan Mode deadlock issue with PlanTaskCounter
- Improved thread synchronization to reduce CPU waste
- Enhanced exception handling to catch all exceptions
- Added comprehensive parameter validation
- Fixed race condition in ThreadCount increment timing
- Implemented IDisposable for proper resource cleanup
- Optimized default SleepTime from 100ms to 10ms
- Optimized memory allocation in GetPlanArr with capacity pre-allocation
- Added IsRunning property for monitoring scaffold state