C#实现多线程编程的简单案例

下面是 C# 实现多线程编程的简单案例的攻略,分为以下几个步骤:

1. 确定需求及问题

在开始之前,需要确定要实现的需求和问题,这样才能更有针对性地编写代码。例如,本次案例要实现的问题可能是:在一个列表中,同时处理多个元素的计算任务,并等待所有计算任务完成后,将结果汇总并输出。

2. 创建多线程

在确定了需求和问题后,需要使用 C# 中的多线程机制来实现。创建线程有两种方法:

  1. 继承 Thread 类:可以定义一个类继承 Thread 类,并覆盖其运行方法 Run(),在此方法中执行需要多线程执行的代码。通过实例化该子类,并调用其 Start() 方法,即可启动一个新的线程。

下面是继承 Thread 类创建多线程的示例代码:

using System;
using System.Threading;

public class MyThread : Thread {
    public string message;

    public MyThread(string message) {
        this.message = message;
        // 在构造函数中,初始化线程对象并设置名称
        this.Name = "MyThread";
        // 设置为后台线程(如果不设置,默认是前台线程)
        this.IsBackground = true;
    }

    // 定义运行方法
    public override void Run() {
        Console.WriteLine(message);
    }
}

// 在主线程中启动 MyThread
public class Program {
    static void Main(string[] args) {
        MyThread mt = new MyThread("Hello, World!");
        mt.Start();
    }
}
  1. 创建委托和线程池:创建一个委托,该委托中执行需要多线程执行的代码,再通过线程池中的线程来执行该委托。

下面是使用线程池创建多线程的示例代码:

using System;
using System.Threading;

public class MyThreadPool {
    public static void DoWork(object state) {
        string message = (string)state;
        Console.WriteLine(message);
    }
}

// 在主线程中使用线程池来执行任务
public class Program {
    static void Main(string[] args) {
        // 将要执行的任务添加到线程池中
        ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadPool.DoWork), "Hello, World!");
        // 确保所有任务都完成了,再执行下一步操作
        ThreadPool.WaitAll(new WaitHandle[0], 5000);
    }
}

3. 多线程间的同步

在多线程编程中,线程间的同步是非常重要的。为了防止线程间访问同一共享资源,导致数据错乱,需要使用特定的方法来进行同步。C# 中常见的同步机制有:

  1. lock 关键字:用于给对象加锁,避免多个线程同时访问造成数据冲突。

下面是使用 lock 关键字进行同步的示例代码:

using System;
using System.Threading;

public class Counter {
    public int count;

    public Counter() {
        count = 0;
    }

    // 原子操作运算
    public void Increment() {
        lock (this) {
            count++;
        }
    }

    // 输出计数器的值
    public void PrintCount() {
        Console.WriteLine("count: " + count);
    }
}

// 使用 Counter 类和 lock 关键字在多线程中同步计数器
public class Program {
    static void Main(string[] args) {
        Counter counter = new Counter();

        // 创建多个线程来执行计数器的增加操作
        Thread t1 = new Thread(new ThreadStart(() => {
            for (int i = 0; i < 100000; i++) {
                counter.Increment();
            }
        }));

        Thread t2 = new Thread(new ThreadStart(() => {
            for (int i = 0; i < 100000; i++) {
                counter.Increment();
            }
        }));

        t1.Start();
        t2.Start();

        // 等待所有线程执行完成
        t1.Join();
        t2.Join();

        // 输出计数器的结果
        counter.PrintCount();
    }
}
  1. Interlocked 类:提供了多种原子性操作方法,可以用于在多线程中进行同步。

下面是使用 Interlocked 类进行同步的示例代码:

using System;
using System.Threading;

public class Counter {
    public int count;

    public Counter() {
        count = 0;
    }

    // 原子操作运算
    public void Increment() {
        Interlocked.Increment(ref count);
    }

    // 输出计数器的值
    public void PrintCount() {
        Console.WriteLine("count: " + count);
    }
}

// 使用 Counter 类和 Interlocked 类在多线程中同步计数器
public class Program {
    static void Main(string[] args) {
        Counter counter = new Counter();

        // 创建多个线程来执行计数器的增加操作
        Thread t1 = new Thread(new ThreadStart(() => {
            for (int i = 0; i < 100000; i++) {
                counter.Increment();
            }
        }));

        Thread t2 = new Thread(new ThreadStart(() => {
            for (int i = 0; i < 100000; i++) {
                counter.Increment();
            }
        }));

        t1.Start();
        t2.Start();

        // 等待所有线程执行完成
        t1.Join();
        t2.Join();

        // 输出计数器的结果
        counter.PrintCount();
    }
}

4. 示例应用

下面是一个简单示例应用,实现了在一个列表中,同时处理多个元素的计算任务,并等待所有计算任务完成后,将结果汇总并输出。

using System;
using System.Collections.Generic;
using System.Threading;

public class Task {
    public int taskId { get; set; }
    public int input { get; set; }
    public int result { get; set; }
    public ManualResetEventSlim evt { get; set; }

    // 构造方法
    public Task(int id, int input) {
        taskId = id;
        this.input = input;
        evt = new ManualResetEventSlim(false);
    }

    // 计算任务的方法
    public void Compute() {
        Thread.Sleep(500); // 模拟耗时计算
        result = input * input;
        evt.Set(); // 完成任务时,通知等待的线程
    }
}

public class Program {
    static void Main(string[] args) {
        // 创建任务列表
        List<Task> taskList = new List<Task>();
        for (int i = 1; i <= 10; i++) {
            taskList.Add(new Task(i, i));
        }

        // 执行计算任务
        foreach (Task task in taskList) {
            ThreadPool.QueueUserWorkItem(new WaitCallback((object state) => {
                Task t = (Task)state;
                t.Compute();
            }), task);
        }

        // 等待所有计算任务完成
        foreach (Task task in taskList) {
            task.evt.Wait();
        }

        // 输出结果
        int sum = 0;
        foreach (Task task in taskList) {
            Console.WriteLine("Task {0}: input={1}, result={2}", task.taskId, task.input, task.result);
            sum += task.result;
        }
        Console.WriteLine("Sum: " + sum);
    }
}

以上就是 C# 实现多线程编程的简单案例的攻略,希望能对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现多线程编程的简单案例 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • 使用扩展函数方式,在Winform界面中快捷的绑定树形列表TreeList控件和TreeListLookUpEdit控件

    在一些字典绑定中,往往为了方便展示详细数据,需要把一些结构树展现在树列表TreeList控件中或者下拉列表的树形控件TreeListLookUpEdit控件中,为了快速的处理数据的绑定操作,比较每次使用涉及太多细节的操作,我们可以把相关的数据绑定操作,放在一些辅助类的扩展函数中进行处理,这样可以更方便的,更简洁的处理数据绑定操作,本篇随笔介绍TreeList…

    C# 2023年4月30日
    00
  • c#判断网络连接状态

    下面是“c#判断网络连接状态”的完整攻略 检测网络连接状态 在 C# 中检测网络连接状态,可以通过检查本机与 Internet 之间是否能够互相访问来实现。 实现该功能,可以通过以下几步完成: 第一步:引入命名空间 在代码文件的顶部,引入 System.Net.NetworkInformation 命名空间。该命名空间包含用于检测网络状态的类。 using …

    C# 2023年5月15日
    00
  • C#实现WPS文件转PDF格式的方法示例

    下面是“C#实现WPS文件转PDF格式的方法示例”的完整攻略。 1. 引言 在现代的办公生活中,文件格式转换是必备的功能之一。实现文件转换的方式也有很多种,其中,利用C#编程实现WPS文件转PDF格式是一种常见的方式。 2. 程序分析 首先,我们需要通过C#代码打开wps文件,然后将其转换为PDF文件。实现此功能需要使用各种C#库和API,其中最常用的就是M…

    C# 2023年6月8日
    00
  • ASP.NET Core中使用Redis实现缓存

    ASP.NET Core中使用Redis实现缓存 在ASP.NET Core应用程序中,缓存是一项非常重要的任务,它可以帮助您提高应用程序的性能和可扩展性。Redis是一种流行的缓存工具,它可以帮助我们管理和缓存数据。在本攻略中,我们将详细讲解如何使用Redis实现缓存,并提供两个示例说明。 步骤一:安装Redis 要使用Redis实现缓存,您需要先安装Re…

    C# 2023年5月17日
    00
  • C#将配置文件appsetting中的值转换为动态对象调用

    将配置文件appsettings中的值转换为动态对象调用,可以使用C#中的Configuration API和ExpandoObject类。 以下是具体实现步骤: 1、添加配置文件 在项目的根目录下,添加一个名为appsettings.json的文件,用于存储应用程序的配置信息: { "AppSettings": { "MyKe…

    C# 2023年5月31日
    00
  • C# DataSet查看返回结果集的实现

    以下是关于“C# DataSet 查看返回结果集的实现”完整攻略的讲解。 什么是 DataSet 首先需要了解什么是 DataSet。DataSet 是 C# 中的一种数据类型,用于表示一组数据集合。DataSet 可以包含多个 DataTable,每个 DataTable 可以包含多个 DataColumn,每个 DataColumn 可以有自己的数据类型…

    C# 2023年5月15日
    00
  • C# winForm自定义弹出页面效果

    接下来我将详细讲解C# WinForm自定义弹出页面效果的完整攻略。我们可以通过以下步骤实现: 1. 创建自定义控件 首先,我们需要创建一个继承自Panel的自定义控件,并设置其BorderStyle为None,这样就可以去掉控件的边框。 public class CustomPanel : Panel { public CustomPanel() { th…

    C# 2023年5月15日
    00
  • C#实现日历效果

    C#实现日历效果的攻略如下: 1. 了解日历的逻辑 在实现日历之前,我们需要了解日历的逻辑。日历的最小单位是日(day),每个月的天数不同,最长可达31天,最短只有28天,还有2月特殊,平年28天,闰年29天。 2. 设计数据结构和算法 在了解日历逻辑后,我们可以开始设计数据结构和算法了。常见的日历视图,可以使用一个二维数组表示,存储天数和日期信息。同时,我…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部