Multi-threading work scaffolding, used to quickly create multi-threaded work code. 多线程工作脚手架,用于快速创建多线程工作代码。
$ dotnet add package MultithreadingScaffoldA lightweight .NET Standard 2.0 library that provides a scaffolding framework for quickly creating multi-threaded work code with minimal boilerplate.
多线程工作脚手架,用于快速创建多线程工作代码的轻量级框架。
Two Operation Modes | 双模式运行
Simple API | 简洁的 API
Resource Management | 资源管理
IDisposable for proper cleanupIDisposable 接口,支持资源清理Advanced Features | 高级特性
dotnet add package MultithreadingScaffoldOr via NuGet Package Manager:
Install-Package MultithreadingScaffold
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
}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();
}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();| 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) |
| 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/>启用控制台调试日志 |
| Property | Type | Description |
|---|---|---|
IsRunning | bool | Indicates if threads are currently active<br/>指示是否有线程正在运行 |
Counter | long | Number of completed work items<br/>已完成的任务数量 |
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");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();
}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();Worker delegate may be called concurrently from multiple threadsMTScaffold instance itself is thread-safe for concurrent worker execution工作委托可能被多个线程并发调用,请确保代码线程安全或使用适当的同步机制。避免在没有适当锁定的情况下使用共享可变状态。MTScaffold 实例本身对于并发工作执行是线程安全的。
using statement or call Dispose() when doneMTScaffold instanceStart() multiple times - create a new instance for each run始终使用 using 语句或调用 Dispose() 方法。释放操作会取消 TTL 任务并中断运行中的线程。不要重用已释放的实例。不能多次调用 Start() - 每次运行需要创建新实例。
ThreadLimit based on workload type (CPU-bound vs I/O-bound)SleepTime for faster thread spawning, but may increase CPU usage普通模式:适合不可预测的工作负载或任务完成速度不同的场景
计划模式:适合统一的工作负载和可预测的执行时间(现已支持动态线程创建)
根据工作负载类型(CPU 密集型 vs I/O 密集型)调整 ThreadLimit
降低 SleepTime 可加快线程启动,但可能增加 CPU 使用率
计划模式现在动态创建线程,结合了预分配的优势和灵活性
Worker are caught and logged (if WriteConsole = true)工作委托中的异常会被捕获并记录(如果 WriteConsole = true)
未处理的异常不会导致整个脚手架崩溃
在工作委托中实现 try-catch 以进行自定义错误处理
失败的任务不会阻止其他任务执行
Thread.Interrupt()Final callback is still invoked after TTL timeoutThreadInterruptedException gracefullyStopwatch (not affected by system time changes)TTL 超时后,所有线程通过 Thread.Interrupt() 中断
TTL 超时后仍会调用 Final 回调
确保工作代码能够优雅地处理 ThreadInterruptedException
TTL 使用 Stopwatch 精确测量(不受系统时间变化影响)
MTScaffold instance can only be started onceStart() multiple times throws InvalidOperationException一次性使用:每个 MTScaffold 实例只能启动一次
多次调用 Start() 会抛出 InvalidOperationException
如需再次运行相同工作负载,请创建新实例
任务执行时间不可预测 希望根据可用性动态创建线程 工作负载为小到中等规模 任务可能失败,希望其他任务继续执行
任务执行时间相似 有大批量统一的任务 希望最小化线程上下文切换 需要可预测的线程数量
Critical Bug Fixes:
Stopwatch instead of DateTime.Now.Second)PlanTaskCounterImprovements:
IDisposable for proper resource cleanupIsRunning property for monitoring scaffold stateSleepTime from 100ms to 10msThreadCount increment timingGetPlanArr with capacity pre-allocationPlan Mode Enhancements:
API Changes:
Start() callsIsRunning read-only propertyMIT License - see LICENSE for details
Contributions are welcome! Please feel free to submit issues or pull requests.
欢迎贡献!请随时提交问题或拉取请求。