C#中的ThreadStart委托

ThreadStart 委托
ThreadStart 是 .NET 中的一个内置委托类型,表示无参数且无返回值的方法。其定义如下:

cs 复制代码
public delegate void ThreadStart();
  • 通常用于定义线程的入口方法。

  • List<ThreadStart>

    这是一个泛型集合,用于存储多个 ThreadStart 委托实例。每个委托代表一个待执行的任务。

  • 整体作用

    创建一个线程任务队列,用于保存需要通过线程执行的多个方法。

2. 典型使用场景

cs 复制代码
private List<ThreadStart> delegates = new List<ThreadStart>();
(1) 多任务队列管理
cs 复制代码
// 添加任务到队列
delegates.Add(() => Console.WriteLine("Task 1"));
delegates.Add(() => File.WriteAllText("test.txt", "Hello"));

// 启动线程执行所有任务
foreach (var task in delegates)
{
    new Thread(task).Start();
}

(2) 延迟执行控制

cs 复制代码
// 先收集任务
delegates.Add(() => DownloadFile(url1));
delegates.Add(() => ProcessData(data));

// 在适当时候触发执行
void ExecuteAllTasks()
{
    foreach (var task in delegates)
    {
        new Thread(task).Start();
    }
}

3. 技术细节

委托与线程的关系
  • 每个 ThreadStart 委托可以传递给 Thread 构造函数,作为线程启动时执行的方法。

  • 示例:

cs 复制代码
ThreadStart task = () => Console.WriteLine("Running in thread");
Thread thread = new Thread(task);
thread.Start();
线程安全注意事项
  • 非线程安全集合
    List<T> 本身不是线程安全的。若多线程同时修改集合(如添加/删除任务),需加锁:
cs 复制代码
private readonly object _lock = new object();

void AddTask(ThreadStart task)
{
    lock (_lock)
    {
        delegates.Add(task);
    }
}

4. 完整使用示例

cs 复制代码
using System;
using System.Collections.Generic;
using System.Threading;

class TaskScheduler
{
    private List<ThreadStart> _tasks = new List<ThreadStart>();
    private readonly object _lock = new object();

    public void AddTask(Action action)
    {
        lock (_lock)
        {
            _tasks.Add(new ThreadStart(action));
        }
    }

    public void ExecuteAll()
    {
        List<Thread> threads = new List<Thread>();
        
        lock (_lock)
        {
            foreach (var task in _tasks)
            {
                Thread thread = new Thread(task);
                threads.Add(thread);
                thread.Start();
            }
            _tasks.Clear();
        }

        // 等待所有线程完成(可选)
        foreach (var thread in threads)
        {
            thread.Join();
        }
    }
}

// 使用示例
var scheduler = new TaskScheduler();
scheduler.AddTask(() => Console.WriteLine("Task 1"));
scheduler.AddTask(() => Thread.Sleep(1000));
scheduler.ExecuteAll();

5. 替代方案(现代C#推荐)

使用 TaskConcurrentQueue
cs 复制代码
using System.Collections.Concurrent;
using System.Threading.Tasks;

private ConcurrentQueue<Action> _taskQueue = new ConcurrentQueue<Action>();

// 添加任务
_taskQueue.Enqueue(() => Console.WriteLine("Task 1"));

// 并行执行
Parallel.ForEach(_taskQueue, task => task.Invoke());
_taskQueue.Clear();
优点
  • 更高效的线程池管理(通过 Task

  • 天生线程安全的集合(ConcurrentQueue

  • 支持 async/await


6. 关键区别:ThreadStart vs Action

特性 ThreadStart Action
返回值 无 (void) 无 (void)
参数 可带参数(如 Action<int>
用途 专用于 Thread 构造函数 通用委托
现代性 较旧 API 推荐使用

总结

  • 原始代码 :创建了一个传统的线程任务队列,适用于需要显式管理 Thread 的场景。

  • 现代替代 :推荐使用 Task + ConcurrentQueue 组合,更符合当前 .NET 的并发编程最佳实践。

  • 线程安全 :若坚持使用 List<ThreadStart>,必须通过锁机制保证线程安全。

根据实际需求选择合适方案,平衡控制精细度和开发效率。

相关推荐
gc_2299几秒前
学习C#调用OpenXml操作word文档的基本用法(21:学习嵌入对象类)
c#·word·openxml·ole
老骥伏枥~11 分钟前
C# if / else 的正确写法与反例
开发语言·c#
老骥伏枥~32 分钟前
C# 运算符优先级易踩坑
c#
SunnyDays10111 小时前
C# 实战:从 Word 文档中提取指定页面
c#·提取word文档页面·将word页面复制到另一个文档
骆驼爱记录1 小时前
Word通配符技巧:高效文档处理指南
开发语言·c#·自动化·word·excel·wps·新人首发
人工智能AI技术2 小时前
智能体元年第一课:使用Microsoft Foundry + AI Toolkit 10分钟构建你的第一个多模态Agent
人工智能·c#
柱子jason2 小时前
基于IOT-Tree Server支持的gRPC服务,使用C#开发自己的设备监控客户端
物联网·rpc·c#·自动化·iiot·iot-tree
骆驼爱记录2 小时前
Word表格题注自动设置全攻略
开发语言·c#·自动化·word·excel·wps·新人首发
Evonso3 小时前
视频转码与切片(HLS)完整教程
c#
lfq7612043 小时前
.NET Framework 下 C# MVC 项目敏感信息安全存储方法
安全·c#·mvc·.net