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

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

问题描述

有谁知道为什么异步方法不允许有 REF 参数呢?我已经做了位或研究,但我能找到的唯一的事情是,它与堆栈展开的事。


解决方案

  

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


当然。想想吧 - 一个异步方法通常返回的几乎立即,很久以前最实际的逻辑被执行...这是异步完成的。因此,任何退出参数将有第一个的await 前pression之前被分配,并且有相当会可能必须要对一些限制REF 参数,第一个的await 前pression后被用于阻止他们无论如何,因为之后,他们甚至可能不是有效的。

考虑调用与异步方法了 REF 参数,使用局部变量的参数:

  INT X;
诠释Y = 10;
FooAsync(出X,REF Y);

FooAsync 的回报,该方法本身可以返回 - 所以那些本地变量将不再存在逻辑......但是异步方法仍然有效能够使用它们在它的延续。大的问题。编译器可以创建一个新的类捕获以同样的方式,它确实对拉姆达前pressions变量,但是这将从别的导致其他问题...一旁,可以有一个的本地变量通过改变方法在任意点,当延续在不同的线程中运行。奇怪,至少可以说。

基本上,它没有意义使用退出 REF 参数异步方法,由于所涉及的定时。使用返回类型,其中包括所有你感兴趣的,而不是数据。

如果你只在退出 REF兴趣第一个等待前pression,你总是可以一分为二的方法:

 公共任务<串GT; FooAsync(OUT INT X,裁判int y)对
{
    //此处赋值为x,也许修改y
    返回FooAsyncImpl(X,Y);
}私人异步任务<串GT; FooAsyncImpl(INT X,int y)对不// ref或out!
{
}

编辑:这将是有使用退出参数可行任务&LT; T&GT; 键,直接在赋值该方法就像返回值。这将是一个有点古怪,虽然,REF 参数,它不会为<$​​ C $ C>工作

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

解决方案

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

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.

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);

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.

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.

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!
{
}

EDIT: 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天全站免登陆