nos*_*tio 14 .net c# multithreading task-parallel-library async-await
难道Delay(0)总要得到内联?根据我的经验,它确实:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个控制台应用程序,因此线程池用于继续.输出:
Main thread: 11
after Yield(), thread: 7
after Delay(0), thread: 7
after Delay(100), thread: 6
Run Code Online (Sandbox Code Playgroud)
Dam*_*ver 22
在里面Task.Delay,它看起来像这样(单个参数(int)版本只调用以下版本):
[__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;
}
Run Code Online (Sandbox Code Playgroud)
你可以希望看到:
if (millisecondsDelay == 0)
{
return CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
这意味着它始终返回已完成的任务,因此您的代码将始终继续运行该特定await行.
是的,它确实.检查反射器中的IL(以及其他逻辑):
if (millisecondsDelay == 0)
{
return CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
所以,是的,在这种情况下,它将把你已经完成的任务交还给你.
请注意,await包含检查的实现包括确保已完成的任务不会导致额外的上下文切换,所以是的:您的代码将继续运行而不会在此处暂停.
当答案已经同步已知/可用时,返回已完成的任务是推荐的技巧; Task为常见结果值缓存s 也很常见.
| 归档时间: |
|
| 查看次数: |
6581 次 |
| 最近记录: |