C#的线程

举报
Rolle 发表于 2024/10/31 00:35:32 2024/10/31
【摘要】 多线程编程是现代软件开发中的一项关键技术,它允许程序同时执行多个任务,从而提高应用程序的响应性和性能。C#提供了丰富的线程管理功能,包括线程的创建、同步、通信和池化等。本文将深入探讨C#中线程的工作原理、使用场景、最佳实践以及一些高级技巧。线程的基本概念在C#中,线程是操作系统中最小的执行单元,是程序执行的最小单位。每个线程都有自己的调用栈和状态信息。主线程与后台线程主线程:程序运行的主要线...

多线程编程是现代软件开发中的一项关键技术,它允许程序同时执行多个任务,从而提高应用程序的响应性和性能。C#提供了丰富的线程管理功能,包括线程的创建、同步、通信和池化等。本文将深入探讨C#中线程的工作原理、使用场景、最佳实践以及一些高级技巧。

线程的基本概念
在C#中,线程是操作系统中最小的执行单元,是程序执行的最小单位。每个线程都有自己的调用栈和状态信息。

主线程与后台线程
主线程:程序运行的主要线程,通常用于UI交互。
后台线程:用于执行后台任务,不会阻止程序退出。
线程的生命周期
线程的生命周期包括新建、就绪、运行、挂起、恢复和终止等状态。

核心API
Thread类
Thread类是C#中最基本的线程管理类,提供了创建和控制线程的方法。

ThreadPool类
ThreadPool是一个线程池,用于管理和复用线程,以提高资源利用率和性能。

Task类
Task是.NET中用于表示异步操作的类,它基于线程池来执行。

Mutex、Semaphore和Monitor
这些类用于线程同步,防止多个线程同时访问共享资源。

创建和启动线程
使用Thread类
using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Thread newThread = new Thread(() => Console.WriteLine(“Hello from a new thread!”));
newThread.Start();
Console.WriteLine(“Hello from the main thread!”);
}
}
使用ThreadPool
using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine(“Hello from ThreadPool thread!”);
});
Console.WriteLine(“Hello from the main thread!”);
}
}
使用Task类
using System;
using System.Threading.Tasks;

class Program
{
static async Task Main(string[] args)
{
Task myTask = Task.Run(() =>
{
Console.WriteLine(“Hello from a Task!”);
});
await myTask;
Console.WriteLine(“Hello from the main thread!”);
}
}
线程同步
使用lock关键字
using System;
using System.Threading;

class Program
{
private static readonly object lockObject = new object();
private static int sharedResource = 0;

static void Main(string[] args)
{
    Thread thread1 = new Thread(Increment);
    Thread thread2 = new Thread Increment);

    thread1.Start();
    thread2.Start();

    thread1.Join();
    thread2.Join();

    Console.WriteLine($"Shared resource value: {sharedResource}");
}

static void Increment()
{
    lock(lockObject)
    {
        for (int i = 0; i < 1000000; i++)
        {
            sharedResource++;
        }
    }
}

}
使用Mutex
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static void Main(string[] args)
{
Mutex mutex = new Mutex();
Task task1 = Task.Run(() =>
{
mutex.WaitOne();
try
{
Console.WriteLine(“Task 1 is executing.”);
Thread.Sleep(2000);
}
finally
{
mutex.ReleaseMutex();
}
});

    Task task2 = Task.Run(() =>
    {
        mutex.WaitOne();
        try
        {
            Console.WriteLine("Task 2 is executing.");
            Thread.Sleep(2000);
        }
        finally
        {
            mutex.ReleaseMutex();
        }
    });

    Task.WhenAll(task1, task2).Wait();
}

}
使用Semaphore
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static void Main(string[] args)
{
Semaphore semaphore = new Semaphore(1, 1);
Task task1 = Task.Run(() =>
{
semaphore.WaitOne();
try
{
Console.WriteLine(“Task 1 is executing.”);
Thread.Sleep(2000);
}
finally
{
semaphore.Release();
}
});

    Task task2 = Task.Run(() =>
    {
        semaphore.WaitOne();
        try
        {
            Console.WriteLine("Task 2 is executing.");
            Thread.Sleep(2000);
        }
        finally
        {
            semaphore.Release();
        }
    });

    Task.WhenAll(task1, task2).Wait();
}

}
使用Monitor
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
private static object lockObject = new object();
private static int sharedResource = 0;

static void Main(string[] args)
{
    Task task1 = Task.Run(() =>
    {
        for (int i = 0; i < 1000000; i++)
        {
            Monitor.Enter(lockObject);
            try
            {
                sharedResource++;
            }
            finally
            {
                Monitor.Exit(lockObject);
            }
        }
    });

    Task task2 = Task.Run(() =>
    {
        for (int i = 0; i < 1000000; i++)
        {
            Monitor.Enter(lockObject);
            try
            {
                sharedResource++;
            }
            finally
            {
                Monitor.Exit(lockObject);
            }
        }
    });

    Task.WhenAll(task1, task2).Wait();

    Console.WriteLine($"Shared resource value: {sharedResource}");
}

}
线程间通信
使用AutoResetEvent和ManualResetEvent
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static AutoResetEvent autoResetEvent = new AutoResetEvent(false);

static void Main(string[] args)
{
    Task producerTask = Task.Run(() =>
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Produced: {i}");
            autoResetEvent.Set();
            Thread.Sleep(1000); // Simulate work
        }
    });

    Task consumerTask = Task.Run(() =>
    {
        for (int i = 0; i < 5; i++)
        {
            autoResetEvent.WaitOne();
            Console.WriteLine($"Consumed: {i}");
        }
    });

    Task.WhenAll(producerTask, consumerTask).Wait();
}

}
使用BlockingCollection
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static void Main(string[] args)
{
BlockingCollection<int> collection = new BlockingCollection<int>(new ConcurrentQueue<int>(), 10);
CancellationTokenSource cts = new CancellationTokenSource();

    Task producerTask = Task.Run(() =>
    {
        for (int i = 0; i < 20; i++)
        {
            collection.Add(i);
            Console.WriteLine($"Produced: {i}");
            Thread.Sleep(1000); // Simulate work
        }
        cts.Cancel();
    });

    Task consumerTask = Task.Run(() =>
    {
        try
        {
            foreach (int item in collection.GetConsumingEnumerable(cts.Token))
            {
                Console.WriteLine($"Consumed: {item}");
            }
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Consuming cancelled.");
        }
    });

    Task.WhenAll(producerTask, consumerTask).Wait();
}

}
高级技巧
线程局部存储
使用ThreadLocal<T>来存储线程特定的数据。
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static ThreadLocal<int> localData = new ThreadLocal<int>(() => 0);

static void Main(string[] args)
{
    Task task1 = Task.Run(() =>
    {
        localData.Value = 1;
        Console.WriteLine($"Task 1 local data: {localData.Value}");
    });

    Task task2 = Task.Run(() =>
    {
        localData.Value = 2;
        Console.WriteLine($"Task 2 local data: {localData.Value}");
    });

    Task.WhenAll(task1, task2).Wait();
}

}
参数化线程
在创建线程时传递参数。
using System;
using System.Threading;

class Program
{
static void ThreadMethod(object o)
{
Console.WriteLine($“Thread {Thread.CurrentThread.ManagedThreadId} says: {o}”);
}

static void Main(string[] args)
{
    Thread newThread = new Thread(new ParameterizedThreadStart(ThreadMethod));
    newThread.Start("Hello from a thread!");
    Console.WriteLine($"Main thread says: {o}");
}

}
定时器线程
使用Timer类来周期性地执行任务
using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Timer timer = new Timer(TimerCallback, null, 0, 1000);
Console.WriteLine(“Press enter to exit…”);
Console.ReadLine();
}

private static void TimerCallback(object state)
{
    Console.WriteLine("Timer callback executed!");
}

}
异步局部变量
使用AsyncLocal<T>来存储异步上下文中的数据。
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static AsyncLocal<int> localData = new AsyncLocal<int>();

static void Main(string[] args)
{
    localData.Value = 1;

    Task task1 = Task.Run(async () =>
    {
        await Task.Delay(1000);
        Console.WriteLine($"Task 1 local data: {localData.Value}");
    });

    Task task2 = Task.Run(async () =>
    {
        await Task.Delay(1000);
        Console.WriteLine($"Task 2 local data: {localData.Value}");
    });

    Task.WhenAll(task1, task2).Wait();
}

}
性能优化
避免过度线程化
创建线程是有成本的,过多的线程会导致上下文切换和资源竞争。

使用线程池
使用线程池可以减少线程创建和销毁的开销。

优化锁的使用
尽量减少锁的使用范围和持有时间,使用读写锁来优化读多写少的场景。

减少线程同步
使用无锁编程技术,如Interlocked类,来减少线程同步的开销

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。