📜  在C#中加入线程(1)

📅  最后修改于: 2023-12-03 15:37:35.247000             🧑  作者: Mango

在C#中加入线程

在C#中,线程是一种轻量级的执行单元,可以并发地执行代码。使用线程可以提高应用程序的性能和响应性。本文将介绍如何在C#中创建和管理线程。

创建线程
使用Thread类创建线程

在C#中,可以使用Thread类来创建线程。以下是创建线程的示例代码:

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread t = new Thread(new ThreadStart(ThreadMethod));
        t.Start();
    }

    static void ThreadMethod()
    {
        Console.WriteLine("New thread started");
    }
}

在上面的代码中,我们创建了一个Thread对象并将其初始化为ThreadStart委托,该委托指示了要在新线程中执行的方法。然后,我们调用Start()方法来启动新线程。

使用Task类创建线程

Task类是.NET 4.0中引入的新类,它提供了一种简单的方法来执行异步任务。以下是使用Task类创建线程的示例代码:

using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Task t = Task.Run(() => {
            Console.WriteLine("New thread started");
        });

        t.Wait();
    }
}

在上面的代码中,我们使用Task.Run()方法来启动新线程,并将要执行的代码作为lambda表达式传递给该方法。

线程同步

在多线程应用程序中,使用线程同步机制可以确保线程之间的协调和安全。以下是常用的线程同步机制:

Lock关键字

Lock关键字可以确保只有一个线程可以访问共享资源。以下是使用lock关键字的示例代码:

class Program
{
    static object lockObject = new object();

    static void Main()
    {
        new Thread(Worker).Start();
        new Thread(Worker).Start();
    }

    static void Worker()
    {
        lock (lockObject)
        {
            Console.WriteLine("Thread {0} is accessing the shared resource", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
        }
    }
}

在上面的代码中,我们使用了一个静态变量lockObject来锁定共享资源。当一个线程进入lock关键字块时,其他线程将等待直到此线程退出lock块。

Monitor类

Monitor类是.NET框架中提供的一组同步原语,在处理一些需要更细粒度的同步时非常有用。以下是使用Monitor类的示例代码:

class Program
{
    static object lockObject = new object();

    static void Main()
    {
        new Thread(Worker).Start();
        new Thread(Worker).Start();
    }

    static void Worker()
    {
        Monitor.Enter(lockObject);

        try
        {
            Console.WriteLine("Thread {0} is accessing the shared resource", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
        }
        finally
        {
            Monitor.Exit(lockObject);
        }
    }
}

在上面的代码中,我们使用了Monitor.Enter()方法来锁定共享资源。在进入Monitor锁定时,Monitor类会记录当前线程ID,并在退出锁定时与线程ID进行匹配。如果不匹配,则会引发异常。

Semaphore类

Semaphore类可以用于限制同时访问共享资源的线程数量。以下是使用Semaphore类的示例代码:

class Program
{
    static Semaphore semaphore = new Semaphore(2, 2);

    static void Main()
    {
        new Thread(Worker).Start();
        new Thread(Worker).Start();
        new Thread(Worker).Start();
        new Thread(Worker).Start();
    }

    static void Worker()
    {
        semaphore.WaitOne();

        try
        {
            Console.WriteLine("Thread {0} is accessing the shared resource", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
        }
        finally
        {
            semaphore.Release();
        }
    }
}

在上面的代码中,我们创建了一个Semaphore对象,并指定允许同时访问共享资源的最大线程数。每当一个线程需要访问共享资源时,它需要调用Semaphore.WaitOne()方法,该方法会减少可用的许可证数量。当线程退出时,它会调用Semaphore.Release()方法,该方法会释放一个许可证。

线程池

线程池是一种可以重用线程的机制,用于处理大量的并发请求。在C#中,可以使用ThreadPool类来访问线程池。以下是使用线程池的示例代码:

class Program
{
    static void Main()
    {
        ThreadPool.QueueUserWorkItem(Worker, "Hello");
        ThreadPool.QueueUserWorkItem(Worker, "World");

        Console.ReadLine();
    }

    static void Worker(object state)
    {
        Console.WriteLine("Thread {0} is processing {1}", Thread.CurrentThread.ManagedThreadId, state);
        Thread.Sleep(1000);
        Console.WriteLine("Thread {0} is done processing {1}", Thread.CurrentThread.ManagedThreadId, state);
    }
}

在上面的代码中,我们使用了ThreadPool.QueueUserWorkItem()方法来将任务放入线程池中。每个任务都会在不同的线程上执行。

总结

在C#中使用线程可以提高应用程序的性能和响应性。我们可以使用Thread类或Task类来创建线程,并使用各种线程同步机制确保线程之间的协调和安全。线程池是另一种可重复使用线程的机制,可用于处理大量并发请求。