I get that I need to await thing in an async marked method to make it asynchronous, but I don't get how to actually end the hole it makes.
static async void Example()
{
int t = await getIntAsync();
WriteLine($"computer: {t}");
}
Since getIntAsync is marked async I have to await in that method or I get a warning. But oh no in the method I await on in getIntAsync I have to mark that as aasync, then unless there is an await in there I get a warning. And so on and so forth to infinity it seems. How do I just make it stop?
I've had a few people tell me to put
await Task.Delay(1000);
In my code, but I know the answer can't be as smelly as putting a delay of a second in all my production code.
A couple others said a task method to end it such as
static Task task()
{
//code
}
But unless I mark that async it throws the same warning that got me into this confusion. I know
static Task task()
{
//code
return Task.FromResult(0);
}
Technically it works, but again that seems too much of a code smell to have all over production.
I just don't get it...
EDIT:
Because it was asked for. I know its a very trivial method, but its also just one I'm using for practice.
static async Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
int n = int.Parse(Console.ReadLine());
return n;
}
What is confusing here is that you don't really do something asynchronous. Console.ReadLine() is a synchronous method. Simply typing async or await somewhere does not magically make this asynchronous.
Since this code is only for testing and learning, one way to make it asynchronous is to put it on another thread using Task.Run() (I would not suggest this for many cases in production code):
static Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
return Task.Run(() => int.Parse(Console.ReadLine());
}
There is no async keyword needed here as you are not awaiting something. You just return a Task<int> that is completed when the user has entered a value and that value was parsed.
And your Example() method then works like that:
static async void Example()
{
int t = await getIntAsync();
WriteLine($"computer: {t}");
}
When the await is hit, the control flow is returned to the caller and the rest of this method (the assignment to t and the call to Console.WriteLine()) are scheduled as a continuation that is executed when the Task<int> returned by getIntAsync() has finished.
The following is needed (async keyword is required and so is the await, it's simply best practice):
The Async keyword
The Await keyword
Some process that you want to work independently while the asynchorous process runs.
Typically, you return value comes from your await task (which should fill in the end hole).
Here is example using a StreamReader,
async Task<string> GetStringFromReaderAsync()
{
Streamreader sr = new StreamReader("filename.txt");
Task<string> getStringTask = sr.ReadLineAsync("filepath");
//Allow user to continue with some other work.
DoFileLookup();
string result = await sr.getStringTask();
return result.ToString();
}
More information here: https://msdn.microsoft.com/en-us/library/system.io.streamreader.readlineasync(v=vs.110).aspx
More about Async and Await: https://msdn.microsoft.com/en-us/library/mt674882.aspx
static async Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
int n = int.Parse(Console.ReadLine());
return n;
}
This will run synchronously as there is no await statement And no awaited call to an async method
the general idea is this
public async Task<int> ExecuteAsync() //Method return type is Task<int>
{
// Error: return type is not int. Return type is Task<int>
return db.SaveChangesAsync();
// OK: returns a task handle that you can await on in you code that called ExecuteAsync()
// you thread continues processing in your calling function until you try to read the value from this return statement.
return await db.SaveChangesAsync();
// Ok. Your Thread leaves here and returns when result available.
// no further Processing done in calling function
return db.SaveChangesAsync().Result;
// Ok. This is not required in this case,
// but if you have an async method that has multiple return points,
// and one of them does not depend on an async method, you can wrap
// the output e.g. return await Task.FromResult(0);
return await Task.FromResult(db.SaveChangesAsync().Result);
return 0; //also ok.
}
Adding on to the other answer below.
static async Task<int> GetIntAsync()
{
Console.Write("Enter the number: ");
return await Task.Run(() => int.Parse("1"));
}
This approach makes something that runs synchronously to be wrapped in a task. However you should never do this (unless of course you know what you are doing) as this spawns another thread. One use case where I have used this is for offloading in webservers but otherwise generally its a bad idea. So while you may have begin with the intention of have maximum utilization of a single thread, you have now ended up with two thread working.
Related
I created a simple example to understand async/await in C#.
class Program
{
static void Main(string[] args)
{
var t = BarAsync();
Console.WriteLine("Main");
}
private static async Task BarAsync()
{
Console.WriteLine("This happens before await");
int i = await QuxAsync();
Console.WriteLine("This happens after await. This result of await is " + i);
}
private static Task<int> QuxAsync()
{
int c = 0;
for (int i = 0; i < int.MaxValue; i++)
{
c++;
}
Console.WriteLine("in the middle processing...");
return Task.FromResult(c);
}
}
So the program prints This happens before await first then count the value from a return method. Afterwards it prints the result.
It looks good. My question is that since await doesn't block the thread that evaluates the async method. My understanding is if the async takes a long time it will return to its calling method.
For my example, because QuxAsync() takes a long time, the code
Console.WriteLine("Main");
is not blocked and will be evaluated very soon.
I think the print order should be
This happens before await
Main
in the middle processing...
This happens after await. This result of await is 2147483647
However it is not, why?
I'll second (third?) others' recommendations that you continue reading and learning about async. I'm partial to my own async intro, but these days there are a number of good ones out there.
My question is that since await doesn't block the thread that evaluates the async method. My understanding is if the async takes a long time it will return to its calling method.
This is the part that is wrong. Asynchrony has absolutely nothing to do with how long something takes.
There's two pieces of knowledge missing, both covered in my async intro.
First: await works by first checking its argument. If it is already completed, then await continues executing - synchronously.
Second: every method is called synchronously. Including async methods. The only time asynchrony happens is when an async method has an await whose argument is not already completed; in that case, that async method returns an incomplete task.
Putting both of these together should explain why your code actually runs synchronously.
This question already has an answer here:
Async Await Running Synchronously
(1 answer)
Closed 2 years ago.
I do not understand when I read the Microsoft documents about async and await working, as it says
Async methods are intended to be non-blocking operations. An await
expression in an async method doesn’t block the current thread while
the awaited task is running. Instead, the expression signs up the rest
of the method as a continuation and returns control to the caller of
the async method.
so consider my code:
public Form1()
{
InitializeComponent();
AsyncTest();
Test(1);
}
private async void AsyncTest()
{
HttpClient client = new HttpClient();
var ss = TT(2);
var s = await ss;
for (int i = 0; i < 10; i++)
{
//loop
}
}
private async Task<int> TT(int i)
{
while (true)
{
if (i > 1000000000)
break;
i++;
}
return i;
}
}
when ever I call AsyncTest(), it just waits behind TT method as it specified with await key, but what does it mean it return control to the main caller??
it is not been returned to the form1, if TT is an infinite loop it just remains forever.
thanks
It seems to me you are a newbee to async-await. You violate several rules about how to use async-await.
To make a function async do the following:
Declare the function async
Return Task<TResult> instead of TResult; return Task instead of void
ONLY EXCEPTION: event handlers return void instead of Task
there should be one await inside your async function. Your compiler will warn you if you omit this.
Make sure that all async functions that you call are awaited for before you return
Guideline: let async be a suffix to your async functions. This allows you to create a sync and an async function that do the same: void MyTest() and Task MyTestAsync()
Following these rules, you can't call an async function from within a constructor. As you are using Winforms your code could be like this:
public Form1()
{
InitializeComponent();
}
public async void OnButton1_Clicked(object sender, ...)
{ // because this is an event handler the return value is void
// Start the first test and await until ready
await TestAsync();
// Start the second test and await until ready:
int i = await TestAsync(1);
}
If you call an async function you know that somewhere inside this function is an await. If you have meaningful things to do while the inner function is awaiting, do not await yet. Do your useful things after the call and await the returned Task as soon as you need the result:
public async void OnButton2_Clicked(object sender, ...)
{
// Start a test, but don't await yet
var task1 = TestAsync(1);
// if here, function TestAsync is awaiting somewhere
// it is not finished yet, so you can't use the result of it
// But you can do Something else:
DoSomethingElse();
// if here you really need the result of TestAsync, await for it
int i = await task1;
// if here you know that TestAsync is finished, i has the proper return value
}
You don't have to start and await the tasks one by one, you can start several tasks and await for them as soon as you need the results:
public async void OnButton3_Clicked(object sender, ...)
{
// start several tasks. Don't await yet:
var task1 = TestAsync(1);
var task2 = TestAsync(2);
var task3 = TestAsync(3);
DoSomethingElse();
// if here I need the results of all three tasks:
var myTasks = new Task[] {task1, task2, task3};
await Task.WhenAll(myTasks);
}
An article that really helped me understanding async-await is this interview with Eric Lippert, where he compares async-await with a cook making breakfast. If a cook has to wait for the water to boil, he doesn't wait idly, but looks around to see if he can do other things. Search somewhere in the middle for async-await.
Another article that helped me following the guidelines of async-await is Async and Await by the ever so helpful Stephen Cleary
Im trying to understand how Lambda expression work with async methods.
I have a function
private int Server_Get_Int(){
Task<int> task = Task.Factory.StartNew<int>( async () => {
FirebaseClient c = Server_Connect();
FirebaseResponse response = await c.GetAsync("todos/set");
return response.ResultAs<int>(); //The response will contain the data being retreived
} );
task.Wait();
int result = task.Result;
Console.WriteLine(result);
return result;
}
I want my async code to run in the lambda expression and get back the result from the server.
But i get back the error:
error CS4010: Cannot convert async lambda expression to delegate type 'Func<int>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<int>'.
It says i can only return a void, task or task<> and to my understanding im returning
task<int>
Is this a problem with what im returning or is this because of async lambda?
Thanks
Edit:
response.ResultAs<int>()
Returns an Int but being inside a Task function it should be returned as a Task
Your whole method is suboptimal. You could rewrite your code to be much simpler. A few comments on your existing code first, however.
You're using Task.Factory.StartNew(), which is dangerous. In
most cases you should simply use Task.Run()
You're using Task.Wait() and Task.Result, which is also suboptimal, not to mention, that Task.Result includes Task.Wait() when accessing it. But I guess, that you want to test the lambda, so it's ok here.
The ResultAs<T>() method converts the response into an int (in your case). The method itself is defined as public virtual T ResultAs<T>(). It needn't return a Task<int>, because your lambda is asynchronous. If you'd remove the async from the lambda you'd have to return a Task<int>, but you can'T do that by simply changing the ResultAs<T> to ResultAs<Task<int>>, you'd have to use a TaskCompletionSource.
Based on the above that we can rewrite your method to this:
private int Server_Get_Int(){
var task = Task.Run(async () => {
var c = Server_Connect();
return (await c.GetAsync("todos/set")).ResultAs<int>();
});
int result = task.Result;
Console.WriteLine(result);
return result;
}
A more concise approach could look like this:
private async Task<int> Server_Get_Int_Async(){
return await Task.Run(async () => {
var c = Server_Connect();
return (await c.GetAsync("todos/set")).ResultAs<int>();
});
}
This creates a new task via Task.Run() and returns that to be completed later.
Based on the comments here are tow ways how you'd call the Server_Get_Int_Asnyc() method. I used explicit types so you can follow my comment, but in almost any case it's better to use var, because the compiler than can choose the best type for the job.
public async Task Foo()
{
// This is the fetch task that's going to be completed sometime in the future. You should almost in any case use configure await on your tasks. For reasons see below.
Task<int> intTask = Server_Get_Int_Async().ConfigureAwait(false);
// Do something other with the task object
// Finally await it and print
int result = await intTask;
Console.WriteLine(result);
}
// Do this if you just need the result and nothing else.
public async Task Bar()
{
int result = await Server_Get_Int_Async().ConfigureAwait(false);
Console.WriteLine(result);
}
In the end it seems, you're pretty new to Task based programming with async/await. I recommend you read the (excellent) introduction article written by Stephen Cleary and go on from there.
The beauty of async/await is, that it propagates naturally through your code and you can write asynchronous code almost like you'd write synchronous code.
Also, placing another article here on why you shouldn't use Wait() or Result to simply get the return value of the async method, since it's going to be noticed much better:
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Test code (console app). This correctly shows "Result: 10".
static void Main(string[] args)
{
Func<Task<int>> func = async () => { await Task.Delay(1000); return 10; };
var task = Task.Factory.StartNew(func);
task.Wait();
int result = task.Unwrap().Result;
WriteLine($"Result: {result}");
ReadKey(true);
}
i go through a msdn sample code where a function is called when button is clicked and when routine is called then Await keyword is used and function has async keyword used.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
int contentLength = await AccessTheWebAsync();
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
}
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
void DoIndependentWork()
{
resultsTextBox.Text += "Working . . . . . . .\r\n";
}
When AccessTheWebAsync is called then await keyword is used, what does it mean?
When this function AccessTheWebAsync() will be executing then DoIndependentWork() function is called and i guess here control will be waiting until this function DoIndependentWork() is finished. Am I right?
again there is another statement called
string urlContents = await getStringTask;
why they use here await. if we do not use await here then what would happen?
Please guide me to understand the code that how it is working.
I have an intro blog post here, and the MSDN docs are also extremely good.
You can think of await as "pausing" the method (without blocking the thread) until the awaitable operation completes. When this happens, it returns a task that is not completed to the calling method, so it also has the option to await.
Here's a brief description about async/await methods.
Async Methods:
Caller is not necessarily blocked for the full execution of async
method
Possible return types
void: “fire-and-forget”
Task: allows to await termination of async method
Task<T>: allows to await termination and get result of type T
No ref or out parameter for async methods
Must again contain an await => Otherwise compile warning
await for Tasks
Await termination of a TPL task
Return result of task (if task with
result type)
Must only occur in async methods => Otherwise compile error
An async method is partly synchronous and partly asynchronous
Caller synchronously executes the method until a blocking await
Thereafter, the method rest is asynchronously executed
async & await Mechanism
Efficient
public async Task<int> GetSiteLengthAsync(string url)
{
HttpClient client = new HttpClient(); <= Sync
Task<string> download1 = client.GetStringAsync(url); <= Sync
string site1 = await download1; <= Async (Another thread)
return site1.Length; <= Async (Another thread)
}
Not sure if that simplier for you to understand that in the following way, but this is how it helped myself:
As you can see, the AccessTheWebAsync returns Task<int> but not just int.
If you would have called it without "await", you would just get the Task<int> object as its result. And could do anything further you want (manually) with that task: for instance, to wait until it finishes theTask.Wait(); and obtain the result of int in theTask.Result.
But await does all that instead of you and returns just int: Task<int> => int.
This is it.
from MSDN:
the await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.await does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
So when the compiler encounter
int contentLength = await AccessTheWebAsync();
it waits till the AccessTheWebAsync() task is complted
please take a look at this example C# Async,Await
All await does is blocks the thread until the result of an async operation returns.
Edit: sorry when I said block I should have said suspend, since blocking would prevent execution from continuing!
Edit2: As Alex pointed out - I should have probably said "execution is suspended" rather than the thread. Basically "Stuff happens until await returns but the point is it appears you are writing and executing synchronous code"
Since async operations have the potential to be take a while (e.g. web service calls), they tend to use callbacks to return a result.
If you have to handle callbacks in your code it can get a little messy, especially when waiting on multiple async tasks that are dependant on each other. Async/await and Task simplify the code so that you can write async code literally in the order you would read it.
e.g. example standard async code with callbacks:
public int CallSomeServiceAndReturnItsValue()
{
int result = 0;
WebService.SomeAsyncServiceCall((svcResult) => { result = svcResult.Value; });
return result;
}
and if you have multiple calls that need to be chained:
public int CallSomeServiceAndReturnItsValue()
{
int result = 0;
WebService.GetSomeIdentifier((svcResult) =>
{
var identifier = svcResult.Value;
WebService.GetResult(identifier, (anotherResult) =>
{
result = anotherResult.Value;
}
}
);
return result;
}
As you can see, it starts getting messy, the code doesn't really read in an order that feels natural. The alternative is to use callback methods instead of anonymous methods but still, the callback methods are far away from the code that called them and things can feel disjointed
The other alternative is of course async/await which is much clearer
public int CallSomeServiceAndReturnItsValue()
{
int identifier = await WebService.GetSomeIdentifier();
return await WebService.GetResult(identifier);
}
How can I wait for a void async method to finish its job?
for example, I have a function like below:
async void LoadBlahBlah()
{
await blah();
...
}
now I want to make sure that everything has been loaded before continuing somewhere else.
Best practice is to mark function async void only if it is fire and forget method, if you want to await on, you should mark it as async Task.
In case if you still want to await, then wrap it like so await Task.Run(() => blah())
If you can change the signature of your function to async Task then you can use the code presented here
The best solution is to use async Task. You should avoid async void for several reasons, one of which is composability.
If the method cannot be made to return Task (e.g., it's an event handler), then you can use SemaphoreSlim to have the method signal when it is about to exit. Consider doing this in a finally block.
You don't really need to do anything manually, await keyword pauses the function execution until blah() returns.
private async void SomeFunction()
{
var x = await LoadBlahBlah(); <- Function is not paused
//rest of the code get's executed even if LoadBlahBlah() is still executing
}
private async Task<T> LoadBlahBlah()
{
await DoStuff(); <- function is paused
await DoMoreStuff();
}
T is type of object blah() returns
You can't really await a void function so LoadBlahBlah() cannot be void
I know this is an old question, but this is still a problem I keep walking into, and yet there is still no clear solution to do this correctly when using async/await in an async void signature method.
However, I noticed that .Wait() is working properly inside the void method.
and since async void and void have the same signature, you might need to do the following.
void LoadBlahBlah()
{
blah().Wait(); //this blocks
}
Confusingly enough async/await does not block on the next code.
async void LoadBlahBlah()
{
await blah(); //this does not block
}
When you decompile your code, my guess is that async void creates an internal Task (just like async Task), but since the signature does not support to return that internal Tasks
this means that internally the async void method will still be able to "await" internally async methods. but externally unable to know when the internal Task is complete.
So my conclusion is that async void is working as intended, and if you need feedback from the internal Task, then you need to use the async Task signature instead.
hopefully my rambling makes sense to anybody also looking for answers.
Edit:
I made some example code and decompiled it to see what is actually going on.
static async void Test()
{
await Task.Delay(5000);
}
static async Task TestAsync()
{
await Task.Delay(5000);
}
Turns into (edit: I know that the body code is not here but in the statemachines, but the statemachines was basically identical, so I didn't bother adding them)
private static void Test()
{
<Test>d__1 stateMachine = new <Test>d__1();
stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncVoidMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
}
private static Task TestAsync()
{
<TestAsync>d__2 stateMachine = new <TestAsync>d__2();
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
neither AsyncVoidMethodBuilder or AsyncTaskMethodBuilder actually have any code in the Start method that would hint of them to block, and would always run asynchronously after they are started.
meaning without the returning Task, there would be no way to check if it is complete.
as expected, it only starts the Task running async, and then it continues in the code.
and the async Task, first it starts the Task, and then it returns it.
so I guess my answer would be to never use async void, if you need to know when the task is done, that is what async Task is for.
do a AutoResetEvent, call the function then wait on AutoResetEvent and then set it inside async void when you know it is done.
You can also wait on a Task that returns from your void async
You can simply change the return type to Task and call await Task.CompletedTask at the end of the function, e.g:
async Task MyFunction() {
await AnotherFunction();
await Task.CompletedTask;
}
I find this simpler than wrapping the whole function body in a call to Task.Run(() => { ... });.
I've read all the solutions of the thread and it's really complicated... The easiest solution is to return something like a bool:
async bool LoadBlahBlah()
{
await blah();
return true;
}
It's not mandatory to store or chekc the return value. You can juste do:
await LoadBlahBlah();
... and you can return false if something goes wrong.