c# - AggressiveInlined 影响 C# 异步方法行为

标签 c# task-parallel-library async-await c#-5.0 methodimplattribute

我有一个 ConcurrentQueue 类型的静态字段:

static readonly ConcurrentQueue<int> q = new ConcurrentQueue<int>();

和一个异步方法:

static async Task<int?> NextNum()
{
    int? n = await Task.Run<int?>(() =>
    {
        int i = 0;

        if (q.TryDequeue(out i)) return i;
        return null;
    });

    return n;
}

然后我执行这段代码:

var nt = NextNum();
q.Enqueue(10);

nt.Wait();
Console.WriteLine("{0}", nt.Result.HasValue ? nt.Result.Value : -1);

输出为10

现在我将 MethodImpl 属性添加到我的异步方法中:

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
static async Task<int?> NextNum()
{
    int? n = await Task.Run<int?>(() =>
    {
        int i = 0;

        if (q.TryDequeue(out i)) return i;
        return null;
    });

    return n;
}

当我执行前面提到的代码时,我得到-1

问题:这是否意味着在异步方法中返回的任务不会立即启动?如果我们添加 MethodImpl (带有 AggressiveInlined)属性,它会立即启动吗?

我想知道用 AggressiveInlined 修饰的方法是否对任务计划程序行为有任何影响。

最佳答案

您的测试是不确定的,因此结果可能会根据计时/线程切换/机器负载/核心数量/等的变化而有所不同。

例如,如果您将测试更改为:

var nt = NextNum();
Thread.Sleep(1000);
q.Enqueue(10);

那么即使没有 AggressiveInlined,输出也很可能是 -1

Question: Does this mean in an async method the returned Task does not start immediately? And if we add MethodImpl (with AggressiveInlining) attribute it starts immediately?

一点也不。 NextNum 返回的任务总是立即开始。但是,通过 Task.Run 排队到线程池的任务可能不会。这就是您看到行为差异的地方。

在您的原始测试中,由 Task.Run 排队的任务恰好花费了足够长的时间,以至于 q.Enqueue 在它之前执行。在第二个测试中,Task.Run 排队的任务恰好在 q.Enqueue 之前运行。两者都是不确定的,AggressiveInlined 只是改变了时间。

评论更新:

I want to know if a method decorated with AggressiveInlining has any effect on task scheduler behavior.

不,事实并非如此。

关于c# - AggressiveInlined 影响 C# 异步方法行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16507270/

相关文章:

c# - 给定类型 ExpressionType.MemberAccess,如何获取字段值?

c# - MVC Controller 有什么特别之处称为属性吗?

c# - 查看从 View 到 Controller 的数据

c# - 尝试同步调用 Async 方法。它永远等待 Task.Result

c# - 后台工作线程中异步等待的调解器死锁 - 如何检测调用自身的线程

c# - Task.Factory.FromAsync 相当于 HttpWebRequest 和请求流代码

c# - 任务.产量();同步 Action (); vs Task.Run(()=>SyncAction());

Swift 组任务不并行运行

c# - 为什么我们不应该将业务逻辑放在服务中?我们会更换我们的服务吗?

javascript - Node : Fully executing websocket responses sequentially with async calls