异步方法中的 ref 和 out 参数 [英] ref and out arguments in async method

查看:28
本文介绍了异步方法中的 ref 和 out 参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道为什么 async 方法不允许有 refout 参数?我已经对它进行了一些研究,但我唯一能找到的是它与堆栈展开有关.

Does anyone know why async methods are not allowed to have ref and out arguments? I've done a bit of research on it but the only thing I could find was that it has to do with the stack unrolling.

推荐答案

有谁知道为什么异步方法不允许有 ref 和 out 参数?

Does anyone know why async methods are not allowed to have ref and out arguments?

当然.想一想 - 异步方法通常返回几乎立即,远在大多数实际逻辑执行之前......这是异步完成的.因此,必须在第一个 await 表达式之前分配任何 out 参数,并且很可能必须对 ref 参数进行一些限制无论如何都要阻止它们在第一个 await 表达式之后被使用,因为之后它们甚至可能无效.

Sure. Think about it - an async method usually returns almost immediately, long before most of the actual logic is executed... that's done asynchronously. So any out parameters would have to be assigned before the first await expression, and there'd quite possibly have to be some restriction on ref parameters to stop them from being used after the first await expression anyway, as after that they may not even be valid.

考虑使用 outref 参数调用异步方法,使用局部变量作为参数:

Consider calling an async method with out and ref parameters, using local variables for the arguments:

int x;
int y = 10;
FooAsync(out x, ref y);

FooAsync 返回后,方法本身可以返回——所以这些局部变量在逻辑上将不再存在……但异步方法仍然可以有效地在其延续中使用它们.大问题.编译器可以创建一个新类来以与 lambda 表达式相同的方式捕获变量,但这会导致其他问题……除此之外,您可以更改 local 变量当延续在不同的线程上运行时,通过方法的任意点.至少可以说很奇怪.

After FooAsync returns, the method itself could return - so those local variables would no longer logically exist... but the async method would still effectively be able to use them in its continuations. Big problems. The compiler could create a new class to capture the variable in the same way that it does for lambda expressions, but that would cause other issues... aside from anything else, you could have a local variable changing at arbitrary points through a method, when continuations run on a different thread. Odd to say the least.

基本上,由于涉及到时间,对 async 方法使用 outref 参数是没有意义的.改用包含您感兴趣的所有数据的返回类型.

Basically, it doesn't make sense to use out and ref parameters for async methods, due to the timing involved. Use a return type which includes all of the data you're interested in instead.

如果您只对在第一个 await 表达式之前更改的 outref 参数感兴趣,您可以随时将方法拆分为二:

If you're only interested in the out and ref parameters changing before the first await expression, you can always split the method in two:

public Task<string> FooAsync(out int x, ref int y)
{
    // Assign a value to x here, maybe change y
    return FooAsyncImpl(x, y);
}

private async Task<string> FooAsyncImpl(int x, int y) // Not ref or out!
{
}

使用 Task 获得 out 参数并像返回值一样直接在方法内分配值是可行的.不过这有点奇怪,它不适用于 ref 参数.

It would be feasible to have out parameters using Task<T> and assign the value directly within the method just like return values. It would be a bit odd though, and it wouldn't work for ref parameters.

这篇关于异步方法中的 ref 和 out 参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆