Task.Yield()与Task.Delay(0) [英] Task.Yield() versus Task.Delay(0)
本文介绍了Task.Yield()与Task.Delay(0)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
确实延迟(0)
总要得到内联?根据我的经验,它的作用:
使用系统;
使用的System.Threading;
使用System.Threading.Tasks;
命名空间ConsoleApplication
{
类节目
{
静态异步任务测试()
{
等待Task.Yield();
Console.WriteLine(后的产率(),螺纹:{0},Thread.CurrentThread.ManagedThreadId);
等待Task.Delay(0);
Console.WriteLine(后的延迟(0),螺纹:{0},Thread.CurrentThread.ManagedThreadId);
等待Task.Delay(100);
Console.WriteLine(后的延迟(100),螺纹:{0},Thread.CurrentThread.ManagedThreadId);
}
静态无效的主要(字串[] args)
{
Console.WriteLine(主要思路:{0},Thread.CurrentThread.ManagedThreadId);
。测试()等待();
}
}
}
这是一个控制台应用程序,从而线程池用于延续。输出:
主线程:11
后的产率(),螺纹:7
后延迟(0),螺纹:7
后延迟(100),螺纹:6
解决方案
在 Task.Delay
,它看起来像这样(单个参数( INT)
版本只是调用下面的版本):
[__ DynamicallyInvokable]
公共静态任务延迟(INT millisecondsDelay,的CancellationToken的CancellationToken)
{
如果(millisecondsDelay< -1)
{
抛出新ArgumentOutOfRangeException(millisecondsDelay,Environment.GetResourceString(Task_Delay_InvalidMillisecondsDelay));
}
如果(cancellationToken.IsCancellationRequested)
{
返回FromCancellation(的CancellationToken);
}
如果(millisecondsDelay == 0)
{
返回CompletedTask;
}
DelayPromise状态=新DelayPromise(的CancellationToken);
如果(cancellationToken.CanBeCanceled)
{
state.Registration = cancellationToken.InternalRegisterWithoutEC(委托(对象状态){
((DelayPromise)状态).Complete();
}, 州);
}
如果(millisecondsDelay!= -1)
{
state.Timer =新的定时器(委托(对象状态){
((DelayPromise)状态).Complete();
},州,millisecondsDelay,-1);
state.Timer.KeepRootedWhileScheduled();
}
返回的状态;
}
正如你所希望看到:
如果(millisecondsDelay == 0)
{
返回CompletedTask;
}
这意味着它总是返回一个完成的任务,因此,您的code将一如既往地继续过去那种特定的运行计谋
行。
Does Delay(0)
always get inlined? In my experience, it does:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication
{
class Program
{
static async Task Test()
{
await Task.Yield();
Console.WriteLine("after Yield(), thread: {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(0);
Console.WriteLine("after Delay(0), thread: {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(100);
Console.WriteLine("after Delay(100), thread: {0}", Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{
Console.WriteLine("Main thread: {0}", Thread.CurrentThread.ManagedThreadId);
Test().Wait();
}
}
}
This is a console app, thus the thread pool is used for continuation. The output:
Main thread: 11
after Yield(), thread: 7
after Delay(0), thread: 7
after Delay(100), thread: 6
解决方案
Inside Task.Delay
, it looks like this (the single parameter (int)
version just calls the below version):
[__DynamicallyInvokable]
public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken)
{
if (millisecondsDelay < -1)
{
throw new ArgumentOutOfRangeException("millisecondsDelay", Environment.GetResourceString("Task_Delay_InvalidMillisecondsDelay"));
}
if (cancellationToken.IsCancellationRequested)
{
return FromCancellation(cancellationToken);
}
if (millisecondsDelay == 0)
{
return CompletedTask;
}
DelayPromise state = new DelayPromise(cancellationToken);
if (cancellationToken.CanBeCanceled)
{
state.Registration = cancellationToken.InternalRegisterWithoutEC(delegate (object state) {
((DelayPromise) state).Complete();
}, state);
}
if (millisecondsDelay != -1)
{
state.Timer = new Timer(delegate (object state) {
((DelayPromise) state).Complete();
}, state, millisecondsDelay, -1);
state.Timer.KeepRootedWhileScheduled();
}
return state;
}
As you can hopefully see:
if (millisecondsDelay == 0)
{
return CompletedTask;
}
Which means it always returns a completed task, and therefore your code will always continue running past that particular await
line.
这篇关于Task.Yield()与Task.Delay(0)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文