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.
Unfortunately in internal state class we can't store the address of an out or ref parameter, basically CLR has no safe way to deal with the address of an object. As consequence the compiler forbid the use of Ref and out parameters in asynchronous method.
You can't have async methods with ref or out parameters.
C# Asynchronous programming: Is it possible to have async methods with ref or out parameters? Unfortunately, because of CLR limitations, we can not do that!
ref is used to state that the parameter passed may be modified by the method. in is used to state that the parameter passed cannot be modified by the method. out is used to state that the parameter passed must be modified by the method.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With