.NET 帮助

C# 线程睡眠方法(开发人员如何使用)

介绍

多线程是现代软件开发的一个重要方面,它允许开发人员同时执行多个任务,从而提高性能和响应速度。 然而,有效管理线程需要仔细考虑同步和协调问题。 Thread.Sleep() 方法是 C# 开发人员管理线程定时和协调的重要工具之一。

在本文中,我们将深入探讨Thread.Sleep()方法的复杂性,探索其目的、用法、潜在的陷阱和替代方案。 此外,在本文中,我们介绍了IronPDF C# PDF库,它可以方便地以编程方式生成PDF文档。

了解 Thread.Sleep()

Thread.Sleep() 方法是 C# 中 System.Threading 命名空间的一部分,用于阻止当前线程的执行指定时间。等待线程或被阻止的线程会停止执行,直到指定的休眠时间结束。Sleep 方法接受一个参数,代表线程应保持不活动状态的时间间隔。该参数可以用毫秒表示,或者作为一个 TimeSpan 对象提供,灵活表达所需的暂停时长。

// Using Thread.Sleep() with a specified number of milliseconds
Thread.Sleep(1000); // block for 1 second
// Using Thread.Sleep() with TimeSpan
TimeSpan sleepDuration = TimeSpan.FromSeconds(2);
Thread.Sleep(sleepDuration); // block for 2 seconds
// Using Thread.Sleep() with a specified number of milliseconds
Thread.Sleep(1000); // block for 1 second
// Using Thread.Sleep() with TimeSpan
TimeSpan sleepDuration = TimeSpan.FromSeconds(2);
Thread.Sleep(sleepDuration); // block for 2 seconds
' Using Thread.Sleep() with a specified number of milliseconds
Thread.Sleep(1000) ' block for 1 second
' Using Thread.Sleep() with TimeSpan
Dim sleepDuration As TimeSpan = TimeSpan.FromSeconds(2)
Thread.Sleep(sleepDuration) ' block for 2 seconds
$vbLabelText   $csharpLabel

Thread.Sleep的用途

使用Thread.Sleep的主要目的是在线程的执行过程中引入延迟或暂停。 这在各种情况下都有好处,例如:

  1. 模拟实时行为: 在应用程序需要模拟实时行为的场景中,引入延迟可以帮助模仿所建模型系统的时间约束。

  2. 防止过度资源消耗:短时间暂停一个线程在不需要持续执行的情境中很有用,这样可以防止不必要的资源消耗。

  3. 线程协调:处理多个线程时,引入暂停可以帮助同步它们的执行,防止竞争条件并确保有序处理。

真实世界示例

让我们考虑一个真实世界的例子,其中Thread.Sleep()方法可以用于模拟交通灯控制系统。 在本场景中,我们将创建一个简单的控制台应用程序,模拟红、黄、绿三色交通信号灯的行为。

using System .Threading;
public class TrafficLightSimulator
{
    static void Main()
    {
        Console.WriteLine("Traffic Light Simulator");
        while (true)
        {
            // Display the red light
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"Stop! Red light - {DateTime.Now.ToString("u")}");
            Thread.Sleep(5000); // Pause for 5 seconds and start execution
            // Display the yellow light
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine($"Get ready! Yellow light - {DateTime.Now.ToString("u")}");
            Thread.Sleep(2000); // Pause for 2 seconds
            // Display the green light
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"Go! Green light - {DateTime.Now.ToString("u")}");
            Thread.Sleep(5000); // Pause for 5 seconds
            // Reset console color
            Console.ResetColor();
            Console.Clear();
        }
    }
}
using System .Threading;
public class TrafficLightSimulator
{
    static void Main()
    {
        Console.WriteLine("Traffic Light Simulator");
        while (true)
        {
            // Display the red light
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"Stop! Red light - {DateTime.Now.ToString("u")}");
            Thread.Sleep(5000); // Pause for 5 seconds and start execution
            // Display the yellow light
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine($"Get ready! Yellow light - {DateTime.Now.ToString("u")}");
            Thread.Sleep(2000); // Pause for 2 seconds
            // Display the green light
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"Go! Green light - {DateTime.Now.ToString("u")}");
            Thread.Sleep(5000); // Pause for 5 seconds
            // Reset console color
            Console.ResetColor();
            Console.Clear();
        }
    }
}
Imports System.Threading
Public Class TrafficLightSimulator
	Shared Sub Main()
		Console.WriteLine("Traffic Light Simulator")
		Do
			' Display the red light
			Console.ForegroundColor = ConsoleColor.Red
			Console.WriteLine($"Stop! Red light - {DateTime.Now.ToString("u")}")
			Thread.Sleep(5000) ' Pause for 5 seconds and start execution
			' Display the yellow light
			Console.ForegroundColor = ConsoleColor.Yellow
			Console.WriteLine($"Get ready! Yellow light - {DateTime.Now.ToString("u")}")
			Thread.Sleep(2000) ' Pause for 2 seconds
			' Display the green light
			Console.ForegroundColor = ConsoleColor.Green
			Console.WriteLine($"Go! Green light - {DateTime.Now.ToString("u")}")
			Thread.Sleep(5000) ' Pause for 5 seconds
			' Reset console color
			Console.ResetColor()
			Console.Clear()
		Loop
	End Sub
End Class
$vbLabelText   $csharpLabel

在上面的程序示例中,我们在 while 循环中进行了一个简单的交通灯模拟。使用 Thread.Sleep() 方法在交通灯信号的转换之间引入延迟。 下面是示例的工作原理:

  1. 程序进入无限循环以模拟连续运行。

  2. 红灯显示 5 秒,代表停止信号。

  3. 5 秒钟后,黄灯显示 2 秒钟,表示进入准备阶段。

  4. 最后,绿灯显示 5 秒钟,允许车辆继续行驶。

  5. 控制台颜色重置,循环重复。

输出

C# 线程睡眠方法(开发人员工作原理):图1 - 程序输出:使用 Thread.Sleep() 方法显示交通灯模拟器。

此示例演示了如何使用Thread.Sleep()来控制交通灯模拟的时序,从而提供一种简单的方法来模拟现实系统的行为。 请记住,这是一个用于说明的基本示例,在更复杂的应用程序中,您可能需要探索更高级的线程和同步技术,以处理用户输入、管理多个交通信号灯并确保精确计时。

在睡眠方法中使用时间跨度超时

您可以使用TimeSpan与Thread.Sleep()方法来指定休眠时间。 下面的示例使用 TimeSpan 扩展了上一个示例中的交通灯模拟:

using System;
using System.Threading;
class TrafficLightSimulator
{
    public static void Main()
    {
        Console.WriteLine("Traffic Light Simulator");
        while (true)
        {
            // Display the red light
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Stop! Red light- {DateTime.Now.ToString("u")}");
            Thread.Sleep(TimeSpan.FromSeconds(5)); // Pause for 5 seconds
            // Display the yellow light
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Get ready! Yellow light-     {DateTime.Now.ToString("u")}");
            Thread.Sleep(TimeSpan.FromSeconds(2)); // Pause for 2 seconds
            // Display the green light
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Go! Green light- {DateTime.Now.ToString("u")}");
            Thread.Sleep(TimeSpan.FromSeconds(5)); // Pause for 5 seconds
            // Reset console color
            Console.ResetColor();
            Console.Clear();
        }
    }
}
using System;
using System.Threading;
class TrafficLightSimulator
{
    public static void Main()
    {
        Console.WriteLine("Traffic Light Simulator");
        while (true)
        {
            // Display the red light
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Stop! Red light- {DateTime.Now.ToString("u")}");
            Thread.Sleep(TimeSpan.FromSeconds(5)); // Pause for 5 seconds
            // Display the yellow light
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Get ready! Yellow light-     {DateTime.Now.ToString("u")}");
            Thread.Sleep(TimeSpan.FromSeconds(2)); // Pause for 2 seconds
            // Display the green light
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Go! Green light- {DateTime.Now.ToString("u")}");
            Thread.Sleep(TimeSpan.FromSeconds(5)); // Pause for 5 seconds
            // Reset console color
            Console.ResetColor();
            Console.Clear();
        }
    }
}
Imports System
Imports System.Threading
Friend Class TrafficLightSimulator
	Public Shared Sub Main()
		Console.WriteLine("Traffic Light Simulator")
		Do
			' Display the red light
			Console.ForegroundColor = ConsoleColor.Red
			Console.WriteLine("Stop! Red light- {DateTime.Now.ToString("u")}")
			Thread.Sleep(TimeSpan.FromSeconds(5)) ' Pause for 5 seconds
			' Display the yellow light
			Console.ForegroundColor = ConsoleColor.Yellow
			Console.WriteLine("Get ready! Yellow light-     {DateTime.Now.ToString("u")}")
			Thread.Sleep(TimeSpan.FromSeconds(2)) ' Pause for 2 seconds
			' Display the green light
			Console.ForegroundColor = ConsoleColor.Green
			Console.WriteLine("Go! Green light- {DateTime.Now.ToString("u")}")
			Thread.Sleep(TimeSpan.FromSeconds(5)) ' Pause for 5 seconds
			' Reset console color
			Console.ResetColor()
			Console.Clear()
		Loop
	End Sub
End Class
$vbLabelText   $csharpLabel

在此修改示例中,TimeSpan.FromSeconds()用于创建一个表示所需休眠持续时间的TimeSpan对象。 这将使代码更具可读性和表现力。

通过在Thread.Sleep()方法中使用TimeSpan属性,您可以直接以秒(或TimeSpan支持的任何其他单位)指定持续时间,从而提供一种更直观的方式来处理时间间隔。 在处理应用程序中更长或更复杂的睡眠时间时,这一点尤其有用。

使用案例

  1. 模拟实时行为:考虑一个模拟应用程序,其中您需要模拟实时系统的行为。 通过在代码中战略性地放置Thread.Sleep(),您可以模拟实际系统中发生的时间延迟,从而提高模拟的准确性。
// Simulating real-time behavior with Thread.Sleep()
SimulateRealTimeEvent();
Thread.Sleep(1000); // Pause for 1 second
SimulateNextEvent();
// Simulating real-time behavior with Thread.Sleep()
SimulateRealTimeEvent();
Thread.Sleep(1000); // Pause for 1 second
SimulateNextEvent();
' Simulating real-time behavior with Thread.Sleep()
SimulateRealTimeEvent()
Thread.Sleep(1000) ' Pause for 1 second
SimulateNextEvent()
$vbLabelText   $csharpLabel
  1. 动画和用户界面更新:在图形化Web开发应用程序或游戏开发中,流畅的动画和用户界面更新至关重要。 Thread.Sleep() 可以用于控制帧率,并确保更新以视觉上令人愉悦的速度发生。
// Updating UI with controlled delays
UpdateUIElement();
Thread.Sleep(50); // Pause for 50 milliseconds
UpdateNextUIElement();
// Updating UI with controlled delays
UpdateUIElement();
Thread.Sleep(50); // Pause for 50 milliseconds
UpdateNextUIElement();
' Updating UI with controlled delays
UpdateUIElement()
Thread.Sleep(50) ' Pause for 50 milliseconds
UpdateNextUIElement()
$vbLabelText   $csharpLabel
  1. 限制外部服务调用:当与外部服务或API交互时,通常会实施速率限制或节流以防止过多的请求。 Thread.Sleep() 可以用于在连续的服务调用之间引入延迟,以保持在速率限制范围内。
// Throttling service calls with Thread.Sleep()
CallExternalService();
Thread.Sleep(2000); // Pause for 2 seconds before the next call
CallNextService();
// Throttling service calls with Thread.Sleep()
CallExternalService();
Thread.Sleep(2000); // Pause for 2 seconds before the next call
CallNextService();
' Throttling service calls with Thread.Sleep()
CallExternalService()
Thread.Sleep(2000) ' Pause for 2 seconds before the next call
CallNextService()
$vbLabelText   $csharpLabel

Thread.Sleep() 的优点

  1. 同步和协调: Thread.Sleep() 有助于同步线程执行,防止竞争条件,并在处理多个线程时确保有序处理。

  2. 资源节约: 在不需要持续执行的情况下,暂时暂停一个线程可以节省系统资源,这在某些情境中是有利的。

  3. 简单性和可读性:该方法提供了一种简单易读的方式来引入延迟,使代码更易于理解,特别是对于刚接触多线程概念的开发者。

潜在陷阱和注意事项

虽然Thread.Sleep()是引入延迟的简单解决方案,但开发人员应注意潜在的陷阱和考虑事项:

  1. 阻塞线程:当使用Thread.Sleep()暂停线程时,它会被有效阻塞,并且在此期间无法执行其他工作。在对响应性要求很高的情况下,长时间阻塞主线程可能会导致糟糕的用户体验。

  2. 时序不准确:暂停持续时间的准确性取决于底层操作系统的调度,可能不够精确。开发人员在依赖Thread.Sleep()来满足精确的时序要求时应谨慎。

  3. 替代方法: 在现代 C# 开发中,通常更倾向于使用 Task.Delay() 方法或使用 async/await 进行异步编程,而不是 Thread.Sleep()。 这些方法可以在不阻塞线程的情况下提供更好的响应能力。
// Using Task.Delay() instead of Thread.Sleep()
await Task.Delay(1000); // Pause for 1 second asynchronously
// Using Task.Delay() instead of Thread.Sleep()
await Task.Delay(1000); // Pause for 1 second asynchronously
' Using Task.Delay() instead of Thread.Sleep()
Await Task.Delay(1000) ' Pause for 1 second asynchronously
$vbLabelText   $csharpLabel

介绍IronPDF

Iron Software 的 IronPDF 是一个 C# PDF 库,可用作 PDF 生成器和阅读器。 本节介绍基本功能。 有关更多详细信息,请查阅IronPDF 文档

IronPDF的亮点是其HTML 到 PDF 转换功能,确保所有布局和样式都得以保留。 它能将网页内容转化为 PDF 文件,可用于报告、发票和文档。 HTML 文件、URL 和 HTML 字符串可以轻松转换成 PDF。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

安装

要安装使用NuGet包管理器的IronPDF,可以使用NuGet包管理器控制台或Visual Studio包管理器。

使用 NuGet 软件包管理器控制台,使用以下命令之一安装 IronPDF 库:

dotnet add package IronPdf
# or
Install-Package IronPdf
dotnet add package IronPdf
# or
Install-Package IronPdf
SHELL

使用 Visual Studio 的软件包管理器安装 IronPdf 库:

C# Thread Sleep 方法(它对开发人员的工作原理):图 2 - 使用 NuGet 包管理器通过在 NuGet 包管理器的搜索栏中搜索 ironpdf 来安装 IronPDF。

using System;
using IronPdf;
class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public void DisplayFullName()
    {
        if (string.IsNullOrEmpty(FirstName) 
 string.IsNullOrEmpty(LastName))
        {
            LogError($"Invalid name: {nameof(FirstName)} or {nameof(LastName)} is missing.");
        }
        else
        {
            Console.WriteLine($"Full Name: {FirstName} {LastName}");
        }
    }
    public void PrintPdf()
    {
        Console.WriteLine("Generating PDF using IronPDF.");
        string content = $@"<!DOCTYPE html>
<html>
<body>
<h1>Hello, {FirstName}!</h1>
<p>First Name: {FirstName}</p>
<p>First Name: {LastName}</p>
</body>
</html>";
        // Create a new PDF document
        var pdfDocument = new ChromePdfRenderer();
        pdfDocument.RenderHtmlAsPdf(content).SaveAs("person.pdf");
    }
    private void LogError(string errorMessage)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"Error: {errorMessage}");
        Console.ResetColor();
    }
}
class Program
{
    public static void Main()
    {
        // Create an  instance of the Person class
        Person person = new Person();
        // Attempt to display the full name
        person.DisplayFullName();
        // Set the properties
        person.FirstName = "John"; // string literal
        person.LastName = "Doe"; // string literal
        // Display the full name again
        person.DisplayFullName();
        Console.WriteLine("Pause for 2 seconds and Print PDF");
        Thread.Sleep(2000); // Pause for 2 seconds and Print PDF
        // Print the full name to PDF
        person.PrintPdf();
    }
}
using System;
using IronPdf;
class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public void DisplayFullName()
    {
        if (string.IsNullOrEmpty(FirstName) 
 string.IsNullOrEmpty(LastName))
        {
            LogError($"Invalid name: {nameof(FirstName)} or {nameof(LastName)} is missing.");
        }
        else
        {
            Console.WriteLine($"Full Name: {FirstName} {LastName}");
        }
    }
    public void PrintPdf()
    {
        Console.WriteLine("Generating PDF using IronPDF.");
        string content = $@"<!DOCTYPE html>
<html>
<body>
<h1>Hello, {FirstName}!</h1>
<p>First Name: {FirstName}</p>
<p>First Name: {LastName}</p>
</body>
</html>";
        // Create a new PDF document
        var pdfDocument = new ChromePdfRenderer();
        pdfDocument.RenderHtmlAsPdf(content).SaveAs("person.pdf");
    }
    private void LogError(string errorMessage)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"Error: {errorMessage}");
        Console.ResetColor();
    }
}
class Program
{
    public static void Main()
    {
        // Create an  instance of the Person class
        Person person = new Person();
        // Attempt to display the full name
        person.DisplayFullName();
        // Set the properties
        person.FirstName = "John"; // string literal
        person.LastName = "Doe"; // string literal
        // Display the full name again
        person.DisplayFullName();
        Console.WriteLine("Pause for 2 seconds and Print PDF");
        Thread.Sleep(2000); // Pause for 2 seconds and Print PDF
        // Print the full name to PDF
        person.PrintPdf();
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

在此程序中,我们演示如何使用 Thread.Sleep 和 IronPDF。 代码最初验证一个人的FirstNameLastName属性。 然后在控制台上打印该人的全名。 然后使用Thread.Sleep等待2秒,随后使用PrintPdf()方法和IronPDF库将FullName打印到PDF。

输出

C# Thread Sleep 方法(它对开发者的作用): 图 3 - 控制台输出:显示在使用 IronPDF 生成 PDF 时使用 Thread.Sleep。

生成 PDF

C# 线程休眠方法(开发人员的工作原理):图 4 - 已创建的输出 PDF。

许可(可免费试用)

要使用 IronPdf,请在 appsettings.json 文件中插入此密钥。

"IronPdf.LicenseKey": "your license key"

要获得试用许可证,请提供您的电子邮件。 有关IronPDF许可的更多信息,请访问此IronPDF许可页面

结论

C#中的Thread.Sleep()方法是管理线程定时和同步的重要工具。 虽然这是一种简单有效的延迟引入解决方案,但开发人员应注意其局限性和对应用程序性能的潜在影响。 随着现代C#开发的发展,探索诸如Task.Delay()和异步编程等替代方法变得至关重要,这对于编写响应迅速且高效的多线程应用程序是必不可少的。 通过了解线程同步的细微差别并选择合适的工具,开发人员可以创建稳健高效的软件,满足动态环境中并发处理的需求。

此外,我们观察到IronPDF功能的多样性在生成PDF文档中的应用,以及它如何与Thread.Sleep方法一起使用。 有关如何使用IronPDF的更多示例,请访问其IronPDF示例页面上的代码示例。

Chipego
软件工程师
Chipego 拥有出色的倾听技巧,这帮助他理解客户问题并提供智能解决方案。他在 2023 年加入 Iron Software 团队,此前他获得了信息技术学士学位。IronPDF 和 IronOCR 是 Chipego 主要专注的两个产品,但他对所有产品的了解每天都在增长,因为他不断找到支持客户的新方法。他喜欢 Iron Software 的合作氛围,公司各地的团队成员贡献他们丰富的经验,以提供有效的创新解决方案。当 Chipego 离开办公桌时,你经常可以发现他在看书或踢足球。
< 前一页
C#空条件运算符(开发人员如何使用)
下一步 >
C# 常量(开发人员如何使用)