How to write an async method with out parameter?
You can't have async methods with ref
or out
parameters.
Lucian Wischik explains why this is not possible on this MSDN thread: http://social.msdn.microsoft.com/Forums/en-US/d2f48a52-e35a-4948-844d-828a1a6deb74/why-async-methods-cannot-have-ref-or-out-parameters
As for why async methods don't support out-by-reference parameters?
(or ref parameters?) That's a limitation of the CLR. We chose to
implement async methods in a similar way to iterator methods -- i.e.
through the compiler transforming the method into a
state-machine-object. The CLR has no safe way to store the address of
an "out parameter" or "reference parameter" as a field of an object.
The only way to have supported out-by-reference parameters would be if
the async feature were done by a low-level CLR rewrite instead of a
compiler-rewrite. We examined that approach, and it had a lot going
for it, but it would ultimately have been so costly that it'd never
have happened.
A typical workaround for this situation is to have the async method return a Tuple instead.
You could re-write your method as such:
public async Task Method1()
{
var tuple = await GetDataTaskAsync();
int op = tuple.Item1;
int result = tuple.Item2;
}
public async Task<Tuple<int, int>> GetDataTaskAsync()
{
//...
return new Tuple<int, int>(1, 2);
}
How to use async await with out parameter in c#
In short, you don't (and you can't), we use a return
Also, when you think about it, it doesn't make any sense, its a task that finishes when it likes, if you could do that you would be forcing it to wait for the out parameter
public async Task<SomeResult> someOtherMethod() { .. }
...
var myAwesomeResult = await someOtherMethod();
Also, you cold use a delegate
, func<T,U>
or Action<T>
as a parameter
public async Task someOtherMethod(Action<bool> someResult)
{
await somestuff;
someResult(true);
}
...
await someOtherMethod(b => YayDoSomethingElse(b));
Ooor as Daniel A. White commented, you could return a ValueTuple
if you need easy access to multiple return types
public async Task<(int someValue,string someOtherValue)> someOtherMethod() {.. }
ref and out arguments in async 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.
Azure Function : async method and output parameters
You are looking for IAsyncCollector<T>
to change from out param to that. Instead of “out string message” you change to ICollector<string> messages
or IAsyncCollector<string>
and add you message to the collection in the body.
Passing Task as parameter to be invoked within loop in async method C#
You are passing the result of calling Print1()
to the method (a Task
). You aren't passing the method itself. So it's only called once at Print1()
. When you await printer;
, it's really just saying "yup, it happened" and moving on.
If you want to pass the method itself, so that it can be called inside PrintLoop
, then you need to accept a Func<Task>
(a method that returns a Task
).
Then you pass the method itself (Print1
) without calling it (not Print1()
)
async Task Main()
{
await PrintLoop(Print1); //not Print1()
}
async Task Print1()
{
Debug.WriteLine("Printing!");
}
async Task PrintLoop(Func<Task> printer, int iterations = 3)
{
for (int i = 0; i < iterations; i++)
{
await printer();
}
}
Related Topics
Resharper "Cannot Resolve Symbol" Even When Project Builds
Handle Modelstate Validation in ASP.NET Web API
SQL Express Connection String: Mdf File Location Relative to Application Location
Cause of Error Cs0161: Not All Code Paths Return a Value
Ienumerable and Recursion Using Yield Return
Embedding an External Executable Inside a C# Program
Why Are Extension Methods Only Allowed in Non-Nested, Non-Generic Static Class
Which Version of C# am I Using
Why Is "Set as Startup" Option Stored in the Suo File and Not the Sln File
How to Install Msbuild on Os X and Linux
What's the Difference Between System.Valuetuple and System.Tuple
Why Do These Division Equations Result in Zero