Span<T> 和异步方法

DrG*_*iff 4 c# async-await

我已经阅读了一些关于Span<T>(and ReadOnlySpan<T>) 以及它们不能用于异步方法的文章。

Jared Parsons 有一段很棒的 Chanel 9 视频,他展示了以下示例:

static async Task<bool> IsCSharpIdentifierAsync(Memory<char> memory, StreamReader reader)
{
    var count = await reader.ReadAsync(memory);
    return IsCSharpIdentifier(memory.Span.Slice(0, count));
}

static bool IsCSharpIdentifier(ReadOnlySpan<char> value)
{
   ....
}

Run Code Online (Sandbox Code Playgroud)

因此,整个流程可能是异步的,但如果我们调用使用 Span 的同步方法,我们就可以了。

现在,我已经很少,如果编译左右任何知识,但我明白,编译器可能(在某些情况下),“在线”的方法(复制从调用的方法到调用方法的代码),以减少的开销方法调用。

我猜答案是“哼哼……当然不是”,但是编译器有没有可能将使用 Span 的方法内联到异步方法中?如果是这样,那会导致我理解的问题......(这包括“本地方法”)

Mar*_*ell 6

C# 编译器从不内联方法;JIT 可能会这样做,但这是一个单独的级别。

但是:在这种情况下,它是否这样做实际上并不是那么重要。阻止您在async方法中使用 ref locals / ref 结构的原因是可能需要将 locals 重写为字段。但是 JIT 内联永远不会创建字段——它只适用于基于本地堆栈的值,而基于本地堆栈的值适用于 ref 值——因为你显然不会await在你的中间有一个同步IsCSharpIdentifier代码。

所以:不要惊慌 - 编译器和 JIT 会在这里看到你。