【开发笔记系列(一)】C#多线程 线程等待

在开发中遇到问题、技术点、解决方法、技术拓展、原理深究,把这些解决过程作为随笔记录下来。所以就有笔记系列,持续更新……

认真探究多线程前,只会new Thread;锁?Lock;线程等待?Thread.Sleep()。

例如 Thread.Sleep()、Thread.SpinWait();、{某种锁}.WaitOne() 等。

这些等待会影响代码的算法逻辑和程序的性能,也有可能会造成死锁,在本篇探究线程中等待。

三种常用等待

这三种等待分别是:

  • Thread.Sleep();
  • Thread.SpinWait();
  • Task.Delay();
函数 注解
Thread.Sleep(); 会阻塞线程,使得线程交出时间片,然后处于休眠状态,直至被重新唤醒;
适合用于长时间的等待;
Thread.SpinWait(); 使用了自旋等待,等待过程中会进行一些的运算,线程不会休眠,用于微小的时间等待;
长时间等待会影响性能;
Task.Delay(); 用于异步中的等待。

这里我们还需要继续 SpinWait 和 SpinLock 这两个类型,最后再进行总结对照。

SpinLock 结构
属性和方法
SpinLock 常用属性和方法如下:

属性:

属性 说明
IsHeld 获取锁当前是否已由任何线程占用。
IsHeldByCurrentThread 获取锁是否已由当前线程占用。
IsThreadOwnerTrackingEnabled 获取是否已为此实例启用了线程所有权跟踪。

方法:

方法 说明
Enter(Boolean) 采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下,
都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。
Exit() 释放锁。
Exit(Boolean) 释放锁。
TryEnter(Boolean) 尝试采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下,
都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。
TryEnter(Int32, Boolean) 尝试采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下,
都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。
TryEnter(TimeSpan, Boolean) 尝试采用可靠的方式获取锁,这样,即使在方法调用中发生异常的情况下,
都能采用可靠的方式检查 lockTaken 以确定是否已获取锁。

示例
SpinLock 的模板如下:

private static void DoWork()
{
	SpinLock spinLock = new SpinLock();
    bool isGetLock = false;     // 是否已获得了锁
    try
    {
    	spinLock.Enter(ref isGetLock);// 运算
    }
    finally
    {
    	if (isGetLock)
         	spinLock.Exit();
    }
}

Thread.Sleep() 会发生上下文切换,出现比较大的性能损失。

posted @   Yan-X  阅读(688)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示