C#实现线程回调的示例代码

 更新时间:2025年12月19日 09:56:02   作者:wangnaisheng  
在 C# 中,线程回调是一种常见的编程模式,用于在线程完成任务后执行某些操作,下面就来详细的介绍一下线程回调的实现,具有一定的参考价值,感兴趣的可以了解一下

在 C# 中,线程回调是一种常见的编程模式,用于在线程完成任务后执行某些操作。通过使用 Thread 类或其他更高层次的并发工具(如 Task),可以实现线程回调的功能。

回调机制

特点

  • 直接性:回调通常是通过委托(Delegate)直接调用的,逻辑简单且明确。
  • 单一目标:回调一般只针对一个特定的目标方法。
  • 轻量级:由于没有额外的中间层(如事件订阅管理),回调的开销较小。

性能分析

  • 调用开销:回调本质上是一个方法调用,性能开销非常低,几乎等同于普通方法调用。
  • 内存分配:通常不会涉及额外的内存分配,除非需要创建闭包或匿名方法。
  • 适用场景
    • 单一任务完成后的通知。
    • 不需要解耦调用方和被调用方的场景。

性能优势

  • 更快的执行速度,因为没有事件订阅和分发的开销。
  • 更少的内存使用,避免了事件管理相关的额外开销。

事件机制

特点

  • 广播性:事件可以支持多个订阅者(多播委托),适合一对多的通知场景。
  • 解耦性:事件将发布者和订阅者解耦,适合复杂系统中的模块化设计。
  • 灵活性:可以通过动态添加或移除事件处理器来改变行为。

性能分析

  • 调用开销
    • 如果只有一个订阅者,事件的性能与回调类似。
    • 如果有多个订阅者,事件需要遍历所有订阅者并逐一调用其处理方法,这会增加开销。
  • 内存分配
    • 事件机制需要维护订阅者的列表,可能会导致额外的内存分配。
    • 如果订阅者频繁地添加或移除,可能会引发垃圾回收的压力。
  • 线程安全
    • 在多线程环境中,事件的订阅和触发可能需要加锁或其他同步机制,进一步增加开销。

性能劣势

  • 多播委托的遍历会导致性能下降,尤其是在订阅者数量较多的情况下。
  • 额外的内存分配和垃圾回收压力可能会影响性能。

性能对比总结

特性回调事件
调用开销低(直接调用方法)较高(可能需要遍历多个订阅者)
内存分配少(通常无额外分配)较多(需要维护订阅者列表)
适用场景单一任务完成后的通知一对多的通知,模块化设计
线程安全性简单(通常无需额外同步)复杂(可能需要加锁)
扩展性较差(只能通知单一目标)较好(支持动态添加/移除订阅者)

以下是实现线程回调的几种方法:

使用Thread类和委托

本文介绍了如何在C#中创建和管理线程以实现并发执行,包括基本步骤、Lambda表达式简化、线程间通信、数据共享与同步,以及ApartmentState在多线程和COM交互中的作用。

using System;
using System.Threading;

class Program
{
    // 定义一个委托,用于回调
    public delegate void CallbackDelegate(string message);

    static void Main(string[] args)
    {
        // 创建线程并传递回调方法
        Thread thread = new Thread(() => DoWork("线程任务完成!", Callback));
        thread.Start();

        Console.WriteLine("主线程继续运行...");
        thread.Join(); // 等待线程完成
    }

    // 模拟线程执行的任务
    static void DoWork(string message, CallbackDelegate callback)
    {
        Console.WriteLine("线程正在执行任务...");
        Thread.Sleep(2000); // 模拟耗时操作
        callback?.Invoke(message); // 调用回调函数
    }

    // 回调方法
    static void Callback(string message)
    {
        Console.WriteLine($"回调执行: {message}");
    }
}

输出:

主线程继续运行...
线程正在执行任务...
回调执行: 线程任务完成!

使用Task和ContinueWith

C# 提供了更高层次的并发工具 Task,可以通过 ContinueWith 实现线程回调。

using System;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        // 创建任务
        Task task = Task.Run(() =>
        {
            Console.WriteLine("任务正在执行...");
            Thread.Sleep(2000); // 模拟耗时操作
        });

        // 使用 ContinueWith 实现回调
        task.ContinueWith(t =>
        {
            Console.WriteLine("回调执行: 任务已完成!");
        });

        Console.WriteLine("主线程继续运行...");
        task.Wait(); // 等待任务完成
    }
}

输出:

主线程继续运行...
任务正在执行...
回调执行: 任务已完成!

使用async/await和回调

结合 async/await 可以更优雅地处理异步操作,并在任务完成后执行回调。

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("主线程继续运行...");

        // 执行异步任务
        await DoWorkAsync();

        // 回调逻辑
        Callback();
    }

    static async Task DoWorkAsync()
    {
        Console.WriteLine("任务正在执行...");
        await Task.Delay(2000); // 模拟耗时操作
    }

    static void Callback()
    {
        Console.WriteLine("回调执行: 任务已完成!");
    }
}

输出: 

主线程继续运行...
任务正在执行...
回调执行: 任务已完成!

使用事件机制

通过定义事件和事件处理器,也可以实现线程完成后的回调。

using System;
using System.Threading;

class Program
{
    // 定义事件
    public static event Action<string> OnTaskCompleted;

    static void Main(string[] args)
    {
        // 订阅事件
        OnTaskCompleted += Callback;

        // 启动线程
        Thread thread = new Thread(() => DoWork("线程任务完成!"));
        thread.Start();

        Console.WriteLine("主线程继续运行...");
        thread.Join(); // 等待线程完成
    }

    static void DoWork(string message)
    {
        Console.WriteLine("线程正在执行任务...");
        Thread.Sleep(2000); // 模拟耗时操作
        OnTaskCompleted?.Invoke(message); // 触发事件
    }

    static void Callback(string message)
    {
        Console.WriteLine($"回调执行: {message}");
    }
}

输出:

主线程继续运行...
线程正在执行任务...
回调执行: 线程任务完成!

总结

  • Thread + 委托:适合简单的线程回调场景。
  • Task + ContinueWith:推荐用于现代 C# 应用,简洁且功能强大。
  • async/await:适用于异步编程,代码更清晰。
  • 事件机制:适合需要解耦的场景,尤其是多个订阅者的情况。

选择合适的方法取决于具体的应用场景和需求。

到此这篇关于C#实现线程回调的示例代码的文章就介绍到这了,更多相关C# 线程回调内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解C#如何使用重载方法实现不同类型数据的计算

    详解C#如何使用重载方法实现不同类型数据的计算

    这篇文章主要为大家详细介绍了C#如何使用重载方法实现不同类型数据的计算,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • C#自定义集合初始化器

    C#自定义集合初始化器

    这篇文章介绍了C#自定义集合初始化器的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • C#的String和StringBuilder详解

    C#的String和StringBuilder详解

    这篇文章主要介绍了C#的String和StringBuilder详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C#利用PaddleOCRSharp实现表格文字识别及可视化对比

    C#利用PaddleOCRSharp实现表格文字识别及可视化对比

    PaddleOCR 是百度飞桨开源的 OCR 工具库,支持多语言文本识别,尤其在中文字符识别上表现优异,在 C# 开发中,我们可以通过 PaddleOCRSharp 封装库快速集成 OCR 功能,本文将通过一个 WinForms 示例,演示如何实现图片和 PDF 中的表格文字识别,需要的朋友可以参考下
    2026-02-02
  • C# Any()和AII()方法的区别

    C# Any()和AII()方法的区别

    本文主要介绍了C# Any()和AII()方法的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • C#中out与ref的区别实例解析

    C#中out与ref的区别实例解析

    这篇文章主要介绍了C#中out与ref的区别实例解析,对C#初学者有不错的学习借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C#实现winform渐变效果的方法

    C#实现winform渐变效果的方法

    这篇文章主要介绍了C#实现winform渐变效果的方法,涉及到窗体的设计与属性的修改等技巧,需要的朋友可以参考下
    2014-10-10
  • C# 海康visionmaster二次开发环境搭建

    C# 海康visionmaster二次开发环境搭建

    本文主要介绍了C# 海康visionmaster二次开发环境搭建,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03
  • 轻松学习C#的String类

    轻松学习C#的String类

    轻松学习C#的String类,小编也是第一次接触C#的String类,感兴趣的小伙伴们可以参考一下,大家一起学习
    2015-11-11
  • C# DataSet查看返回结果集的实现

    C# DataSet查看返回结果集的实现

    这篇文章主要介绍了C# DataSet查看返回结果集的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10

最新评论