C# 中的 Thread.Sleep()
在本指南中,我们将了解为什么在 C# 中使用 thread.sleep()
被认为是有害的,以及为什么不应该使用这种特殊方法。
使用 thread.sleep()
会发生什么?有没有替代方法?
找出本指南中的所有内容。让我们深入了解一下。
为什么 thread.sleep()
在 C#
中是有害的
要理解 thread.sleep()
为何有害,我们必须了解此方法背后的工作。好吧,在 C# 中,sleep
方法有其用途。
你可以使用它在特定时间段内暂停或暂停当前功能(线程执行)。我们可以通过以毫秒为单位的时间来暂停线程执行一段时间。
我们还可以使用 TimeSpan
属性,如下面的代码所示。
// Time in milliseconds
Thread.Sleep(5000);
Or
// Time in hours, minutes, seconds
TimeSpan tsObj = new TimeSpan(0, 0, 5);
Thread.Sleep(tsObj);
现在,上述两种方法都会停止程序五秒钟。这意味着,通过上面的代码,我们试图将线程挂起 1 秒。
但是,这一切的意义何在?让我们了解它的工作原理。
thread.sleep()
如何在 C#
中工作
我们都知道一个程序逐行运行,这意味着整个程序同步运行,一行接一行。有时,在编程过程中,我们需要执行一项需要一些时间才能完成的任务。
例如,从 API 获取数据,我们可以使用 sleep
函数让它等待,从 API 获取数据,然后运行程序的其余部分。这是必要的,但却是一种非常有害和糟糕的方法。
例如,我们试图获取的数据可能很大并且需要时间。我们的程序将在此期间停止;这不是一个理想的方法。
Thread.Sleep(n)
意味着在 n
毫秒内尽可能多的时间片(也称为线程量子)停止正在运行的线程。时间片的持续时间取决于 Windows 的版本/类型和使用的处理器,但通常持续 15 到 30 毫秒。
这表明线程可能会阻塞超过 n
毫秒。你的线程不太可能在 n
毫秒后精确地重新唤醒。
因此,Thread.Sleep
在计时方面没有任何作用。
线程是一种有限资源,需要大约 200,000 次循环创建和 100,000 次循环销毁。默认情况下,他们为每个上下文转换使用 2,000–8,000 个周期,并为他们的堆栈保留 1 兆字节的虚拟内存。
什么是替代方法
我们有时需要延迟我们的线程以使程序完美运行。如上所述,我们可能需要获取一些 API 数据,这需要时间。
但是因为它而停止整个程序是一种不好的方法。那么,我们该如何避免呢?
让我们向你介绍异步编程。
异步编程
C# 中的 async
和 await
关键字有助于使异步编程在当今变得非常普遍。整个应用程序在使用 UI 时将不得不等待完成操作并使用需要很长时间的长时间运行的方法,例如读取一个巨大的文件或单击一个按钮。
换句话说,如果同步应用程序中的任何进程被阻塞,整个应用程序也会停止,我们的应用程序将停止运行,直到整个任务完成。
在这种情况下,异步编程非常有用。通过采用异步编程,应用程序可以继续执行不依赖于完成的任务。
借助 async
和 await
关键字,我们将以更少的工作实现传统异步编程的所有优点。
同时运行两个方法(C# 中的 async
和 await
关键字)
假设我们有两个方法,FirstMethod()
和 SecondMethod()
,它们彼此独立,并且 FirstMethod()
需要很长时间才能执行其任务。
同步编程从 FirstMethod()
开始并等待它完成,然后再继续执行 SecondMethod()
。即使这两个过程是独立的,这个过程也会花费很多时间。
我们可以通过使用简单的线程编程同时运行所有功能,但这会在我们等待任务完成时阻塞用户界面。在传统的编程中,我们需要编写大量的代码来解决这个问题,但是如果我们使用 async
和 await
关键字,我们可以用更少的代码解决这个问题。
我们还将看到其他示例,在这些情况下,当 SecondMethod()
依赖于 FirstMethod()
时,它将使用 await
关键字等待 FirstMethod()
完成运行。
在 C# 中,async
和 await
是代码标记,用于指示当任务完成时控件应返回的位置。
从真实世界的示例开始将帮助你更好地理解它们背后的编程。看看下面的代码。
class Program {
static void Main(string[] args) {
FirstMethod();
SecondMethod();
Console.ReadKey();
}
public static async Task FirstMethod() {
await Task.Run(() => {
for (int i = 0; i < 100; i++) {
Console.WriteLine(" First Method");
// Do something
Task.Delay(100).Wait();
}
});
}
public static void SecondMethod() {
for (int i = 0; i < 25; i++) {
Console.WriteLine(" Second Method ");
// Do something
Task.Delay(100).Wait();
}
}
}
上述代码的输出将如下所示。
First Method
Second Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
Second Method
Second Method
Second Method
Second Method
正如你在上面的代码中看到的那样,整个程序不会因为我们必须停止执行一个线程而停止。它们都可以使用异步编程同时运行。
假设你在某个时刻必须获取一些 API 数据,这需要时间。因此,程序将在没有获取数据的情况下移动到下一行,因此我们需要稍微延迟一下以获取该数据,然后再移动到下一行。
相关文章
C# 中的 extern 关键字
发布时间:2024/01/20 浏览次数:125 分类:编程语言
-
在今天的文章中,我们将学习 C# 中 extern 关键字的功能。在今天的文章中,我们将学习 C# 中 extern 关键字的功能。
C# 将 Int 转换为 Char
发布时间:2024/01/20 浏览次数:137 分类:编程语言
-
本教程教授如何在 C# 中将 int 转换为 char。在 C# 中使用显式类型转换 Char 将 Int 转换为 Char
在 C# 中创建泛型函数
发布时间:2024/01/20 浏览次数:186 分类:编程语言
-
我们可以使用类型 T 在 C# 中声明一个泛型数据类型。它既可以用作函数返回类型,也可以用作函数参数的数据类型。
在 C# 中按值对字典排序
发布时间:2024/01/19 浏览次数:153 分类:编程语言
-
有两种主要方法可用于按 C# 中的值对字典进行排序:list 方法和 Linq 方法。使用 C# 中的 List 方法按值对字典进行排序。C# 字典数据结构以 key:value 对的形式存储数据。
在 C# 中更新字典值
发布时间:2024/01/19 浏览次数:72 分类:编程语言
-
本教程演示如何使用键作为索引来更新 C# 字典中的值。dictionary 是一种集合类型,与只能通过索引或值本身访问值的数组或列表不同,字典使用键和值对来存储其数据。
在 C# 中检查字典键是否存在
发布时间:2024/01/19 浏览次数:142 分类:编程语言
-
本文教我们如何检查或检测 C# 中是否存在字典键。Dictionary 倾向于映射键和值。它包含特定值映射到的特定键。不允许有重复的键,这是字典的全部目标。
C# 中的字典与哈希表
发布时间:2024/01/19 浏览次数:166 分类:编程语言
-
本指南将讨论 C# 中 Dictionary 和 Hashtable 之间的区别。你应该更喜欢哪一个?本指南将讨论 C# 中 Dictionary 和 Hashtable 之间的区别。
将 JSON 字符串转换为 C# 对象
发布时间:2024/01/19 浏览次数:73 分类:编程语言
-
本教程演示如何使用 Newtonsoft.Json 包或 JavaScriptSerializer 提供的 DeserializeObject 函数将 JSON 字符串转换为 C#