C#/.NET 中 Thread.Sleep(0), Task.Delay(0), Thread.Yield(), Task.Yield() 不同的执行效果和用法建议

本文详细探讨了 C#/.NET 中 Thread.Sleep(0)、Thread.Yield()、Thread.Sleep(1)、Task.Delay(0)、Task.Yield() 和 Task.Delay(1) 的原理和用法区别。这些方法都涉及线程调度,但具体行为和适用场景有所不同。Thread.Sleep(0) 和 Thread.Yield() 主要用于放弃当前线程的 CPU 时间片,而 Task.Delay(0) 和 Task.Yield() 则与异步编程模型相关,后者能立即返回。在选择使用这些方法时,需要根据是否需要异步上下文、线程池调度以及是否希望阻塞线程来决定。
摘要由CSDN通过智能技术生成

在 C#/.NET 中,有 Thread.Sleep(0), Task.Delay(0), Thread.Yield(), Task.Yield() 中,有几种不同的让当前线程释放执行权的方法。他们的作用都是放弃当前线程当前的执行权,让其他线程得以调度。但是他们又不太一样。

本文说说他们的原理区别和用法区别。


原理区别

Thread.Sleep(0)

Thread.Sleep(int millisecondsTimeout) 的代码贴在下面,其内部实际上是在调用 SleepInternal,而 SleepInternal 由 CLR 内部实现。其目的是将当前线程挂起一个指定的时间间隔。

如果将超时时间设置为 0,即 Thread.Sleep(0),那么这将强制当前线程放弃剩余的 CPU 时间片。

放弃当前线程剩余的 CPU 时间片就意味着其他比此线程优先级高且可以被调度的线程将会在此时被调度。然而此方法只是放弃当前 CPU 执行的时间片,如果当前系统环境下其他可以被调度的其他线程的优先级都比这个线程的优先级低,实际上此线程依然还是会优先执行。

如果你的方法不会被其他线程影响,那么不会有执行上的区别,但如果你的方法涉及到多个线程的调用,那么 Thread.Sleep(0) 的调用可能导致其他线程也进入此方法(而不是等此线程的当前时间片执行完后再进入)。当然,CPU 对单个线程的执行时间片是纳秒级别的,所以实际上你因为此方法调用获得的多线程重入效果是“纯属巧合”的。

/*=========================================================================
** Suspends the current thread for timeout milliseconds. If timeout == 0,
** forces the thread to give up the remainer of its timeslice.  If timeout
** == Timeout.Infinite, no timeout will occur.
**
** Exceptions: ArgumentException if timeout < 0.
**             ThreadInterruptedException if the thread is interrupted while sleeping.
=========================================================================*/
[System.Security.SecurityCritical]  // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout);

[System.Security.SecuritySafeCritical]  // auto-generated
public static void Sleep(int millisecondsTimeout)
{
   
    SleepInternal(millisecondsTimeout);
    // Ensure we don't return to app code when the pause is underway
    if(AppDomainPauseManager.IsPaused)
        AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
}

Thread.Yield()

Thread.Yield() 的代码贴在下面,其内部调用 YieldInternal,实际上也是由 CLR 内部实现。

此方法也是放弃当前线程的剩余时间片,所以其效果与 Thread.Sleep(0) 是相同的。

[System.Security.SecurityCritical]  // auto-generated
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[HostProtection(Synchronization = true, ExternalThreading = true),
    ReliabilityContract(Consistency.WillNotCorruptState,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值