I have a C# Windows Store app with a streamsocket listener running in a task waiting for commands to come in over the network. I need to make sure each command is fully processed before doing the next one.
The listener takes a raw message and does
await ProcessMessage(message);
which is
private async Task ProcessMessage(string message, string optionalFlags = "")
Which parses the message and calls one of many methods, i.e.
ProcessCommandXYZ(parameters);
This seems to work, but in the async task ProcessMessage line I get a CS1998 "async method lacks 'await'" warning, and searching says if you get this message you're probably not using async correctly.
Is my approach correct and can I ignore this warning, or is there a better way to do this?
Update
I realize a lot of my problem is one of the methods is updating the state which is bound to a listview, so it's in a UI dispatcher and makes it get out of sync and I was awaiting it's ProcessCommandABC(). Since it's just the one method I believe I can optimize if that's best and don't await the one method?
The purpose of using async is so that you can use the keyword await in that function/method. Because the ProcessMessage method is not doing any awaits inside it, the compiler is giving you that warning. The solution is simple: remove the async from ProcessMessage. The use of await by a caller does not require that the method it is calling be declared with async. The method just needs to be returning a Task or Task<T>.
As mentioned by #Mayoor, the lack of awaits in the ProcessMessage suggests it is doing synchronous work, in which case it shouldn't be async. Declaring a method as async does not make it asynchronous it simply allows you to use await inside it to wait for asynchronous work to complete.
if the work is synchronous, you can run it in the background using Task.Run which you can await. So one possible solution is to make your ProcessMessage method synchronous and then just call
await Task.Run(() => ProcessMessage(...));
You can learn more about async-await best practices in this article.
Related
public async Task GetLiveCandleStick(string param)
{
await Clients.All.SendAsync("ReceiveMessage", param);
}
Please consider the above code.
Almost all of the tutorial await Clients.xxx.SendAsync methods. However, I find that it works fine even I take away the await keyword. Then what is the point of using await? (I have seen a thread explaned that await is not meant to "wait until client receive the message...")
Thanks in advance.
By omitting the await keyword, the method would become fire-and-forget; this is almost never the right thing to do, as you would have no way of knowing that the Task had completed.
Another issue is exception handling. If an exception occurs when you call SendAsync, it is placed on the Task rather than being thrown directly, and would simply be garbage collected without using await.
Having said this, if your GetLiveCandleStick method is a simple wrapper as you suggest, it would be slightly more efficient to simply return the Task from SendAsync rather than create a new one using async:
public Task GetLiveCandleStick(string param)
{
return Clients.All.SendAsync("ReceiveMessage", param);
}
In this case only, you don't need to use await - nothing else is happening after SendAsync so there's no need to await. Awaiting on GetLiveCandleStick would behave the same as awaiting on SendAsync. You could convert this method to :
public Task GetLiveCandleStick(string param)=> Clients.All.SendAsync("ReceiveMessage", param);
Tutorials use await because quite often there is code after SendAsync, that should be executed after SignalR enqueues the message.
You may want to add error handling in case SignalR throws for example, or ensure a Begin message is enqueued after an End message in a tight loop. Having an await even for a single statement method can be useful for debugging too.
Finally, good tutorials shouldn't introduce unrelated concepts as this can easily lead to confusion. A SignalR tutorial isn't the best place for explaining the await state machine, or when await can be skipped. Unfortunately, too many examples in learn.microsoft.com try to put everything into a single page, resulting in quite a bit of confusion.
The keyword "await" is for async methods. It's smarter than "wait", it's async wait!
This means that wait the return of message during exec the code until the result is necessary used. So You don't have to use Thread.Wait in a line of code, but the compiler place the wait in the right position. In this case the method that call the await is async, so the wait of Clients.All.SendAsync is out of function.
I've been stuck on this question for a while and haven't really found any useful clarification as to why this is.
If I have an async method like:
public async Task<bool> MyMethod()
{
// Some logic
return true;
}
public async void MyMethod2()
{
var status = MyMethod(); // Visual studio green lines this and recommends using await
}
If I use await here, what's the point of the asynchronous method? Doesn't it make the async useless that VS is telling me to call await? Does that not defeat the purpose of offloading a task to a thread without waiting for it to finish?
Does that not defeat the purpose of offloading a task to a thread without waiting for it to finish?
Yes, of course. But that's not the purpose of await/async. The purpose is to allow you to write synchronous code that uses asynchronous operations without wasting threads, or more generally, to give the caller a measure of control over the more or less asynchronous operations.
The basic idea is that as long as you use await and async properly, the whole operation will appear to be synchronous. This is usually a good thing, because most of the things you do are synchronous - say, you don't want to create a user before you request the user name. So you'd do something like this:
var name = await GetNameAsync();
var user = await RemoteService.CreateUserAsync(name);
The two operations are synchronous with respect to each other; the second doesn't (and cannot!) happen before the first. But they aren't (necessarily) synchronous with respect to their caller. A typical example is a Windows Forms application. Imagine you have a button, and the click handler contains the code above - all the code runs on the UI thread, but at the same time, while you're awaiting, the UI thread is free to do other tasks (similar to using Application.DoEvents until the operation completes).
Synchronous code is easier to write and understand, so this allows you to get most of the benefits of asynchronous operations without making your code harder to understand. And you don't lose the ability to do things asynchronously, since Task itself is just a promise, and you don't always have to await it right away. Imagine that GetNameAsync takes a lot of time, but at the same time, you have some CPU work to do before it's done:
var nameTask = GetNameAsync();
for (int i = 0; i < 100; i++) Thread.Sleep(100); // Important busy-work!
var name = await nameTask;
var user = await RemoteService.CreateUserAsync(name);
And now your code is still beautifuly synchronous - await is the synchronization point - while you can do other things in parallel with the asynchronous operations. Another typical example would be firing off multiple asynchronous requests in parallel but keeping the code synchronous with the completion of all of the requests:
var tasks = urls.Select(i => httpClient.GetAsync(i)).ToArray();
await Task.WhenAll(tasks);
The tasks are asynchronous in respect to each other, but not their caller, which is still beautifuly synchronous.
I've made a (incomplete) networking sample that uses await in just this way. The basic idea is that while most of the code is logically synchronous (there's a protocol to be followed - ask for login->verify login->read loop...; you can even see the part where multiple tasks are awaited in parallel), you only use a thread when you actually have CPU work to do. Await makes this almost trivial - doing the same thing with continuations or the old Begin/End async model would be much more painful, especially with respect to error handling. Await makes it look very clean.
If I use await here, what's the point of the asynchronous method?
await does not block thread. MyMethod2 will run synchronously until it reaches await expression. Then MyMethod2 will be suspended until awaited task (MyMethod) is complete. While MyMethod is not completed control will return to caller of MyMethod2. That's the point of await - caller will continue doing it's job.
Doesn't it make the async useless that VS is telling me to call await?
async is just a flag which means 'somewhere in the method you have one or more await'.
Does that not defeat the purpose of offloading a task to a thread
without waiting for it to finish?
As described above, you don't have to wait for task to finish. Nothing is blocked here.
NOTE: To follow framework naming standards I suggest you to add Async suffix to asynchronous method names.
An async method is not automatically executed on a different thread. Actually, the opposite is true: an async method is always executed in the calling thread. async means that this is a method that can yield to an asynchronous operation. That means it can return control to the caller while waiting for the other execution to complete. So asnync methods are a way to wait for other asynchronoous operations.
Since you are doing nothing to wait for in MyMethod2, async makes no sense here, so your compiler warns you.
Interestingly, the team that implemented async methods has acknowledged that marking a method async is not really necessary, since it would be enough to just use await in the method body for the compiler to recognize it as async. The requirement of using the async keyword has been added to avoid breaking changes to existing code that uses await as a variable name.
When we are dealing with async tasks, the task consists of multiple method calls (possibly of other classes) which in turn consist of yet further method calls. We could call this a tree. Do all methods have to be of type async task for the original task to truly behave async?
Would the answer be true for any kind of background task of other similar languages, mostly Java as well?
(In C#, once I had one of my methods somewhere in this tree get into an infinite loop (talk about a long running task!), yet sadly, the original async task's isRunning property returned false.)
Do all methods have to be of type async task for the original task to truly behave async?
In order to behave asynchronously, an async method must have an await statement for an operation that is not already completed.
I think my async intro blog post would be helpful for you.
Would the answer be true for any kind of background task of other similar languages, mostly Java as well?
Yes.
sadly, the original async task's isRunning property returned false
I assume you mean that the TaskStatus was not TaskStatus.Running. This is normal and expected, since asynchronous tasks are Promise Tasks, not Delegate Tasks (see my blog for more info).
The short answer is no. Async means that work being done by another process can be handed off to that process and so not block the calling thread. All the better if those processes don’t reside on the same machine, since that work will occupy very little compute or IO at the caller. This is achieved by suspending method execution using the async/await mechanism, which promises to resume on some synchronisation context once completed. So, why the overview?
Because this means that we can and should judiciously choose those operations that should be async, and so apply the await keyword in an async method. Some won’t need it, since they are lightweight and adding async to them may even add compute time to them, due to the creation of the async state machine. So the operations in a method can often be a mixture of asynchronous and synchronous code.
And this in turn means that some methods would use the Task return type with async/await, and some will be regular, synchronous methods.
No, they don't have to. Simple example, in a Forms application this
button.Click += async (_, __) =>
{
await Task.Run(() => MyClass.SomeTimeconsumingMethod());
};
still lets you move the window during the execution of SomeTimeconsumingMethod, whereas this one
button.Click += (_, __) =>
{
MyClass.SomeTimeconsumingMethod();
};
doesn't let you do it.
The only requirement for using the await keyword is that the method you are awaiting returns a Task or Task<T>.
The exact implementation of this method (async or return someTask) has no influence on the correctness of the code, although it may influence the function.
Any normal code can run in an async method alongside your await calls. The only significant restriction is that out and ref are not allowed.
Do all methods have to be of type async task for the original task to truly behave async
It depends on what do you mean by "all" word.
Some APIs must not be asynchronous. Think about List<T>.Add, for example. Do you really want it to be asynchronous?
Some APIs should be asynchronous, but there's no asynchronous counterpart (e.g. SMO, or File static class).
Ideally you should do "async all the way", when talking about IO-bound operations. But IRL you can face with violation of this rule, when some part of your async method chain will execute IO-bound operation synchronously.
I would like to get some clarification on what is the added benefit of using of Await and Async all the way down.
If my application is calling await Func1() (So no blocking to the UI here). and Func1 is calling await Func2(), but the results from Func2() are important for Func1 to complete it's job, then why would I need to make Func2() awaitable. Func1() execution will take just as long because it's waiting on Func2 to finish. All what the await is doing here is adding the StateMachine overhead.
Am I missing something here?
A better slogan is async all the way up. Because you start with an asynchronous operation and make its caller asynchronous and then the next caller etc.
You should use async-await when you have an inherently asynchronous operation (usually I/O but not necessarily) and you don't want to waste a thread idly waiting for the operation to complete. Choosing an async operation instead of a synchronous one doesn't speed up the operation. It will take the same amount of time (or even more). It just enables that thread to continue executing some other CPU bound work instead of wasting resources.
But to be able to await that operation the method needs to be an async one and the caller needs to await it and so forth and so forth.
So async all the way up enables you to actually make an asynchronous call and release any threads. If it isn't async all the way then some thread is being blocked.
So, this:
async Task FooAsync()
{
await Func1();
// do other stuff
}
async Task Func1()
{
await Func2();
// do other stuff
}
async Task Func2()
{
await tcpClient.SendAsync();
// do other stuff
}
Is better than this:
void Foo()
{
Func1();
// do other stuff
}
void Func1()
{
Func2().Wait(); // Synchronously blocking a thread.
// do other stuff
}
async Task Func2()
{
await tcpClient.SendAsync();
// do other stuff
}
The major benefit is the fact that awaiting an asynchronous method returns the worker thread to the pool to be used in other calls (web requests to your .NET MVC web app, for example). The asynchronous work is done on an IO completion thread. When the awaited method finishes, another worker thread will collect the results and resume execution. This prevents worker thread pool exhaustion and allows your application to handle more load (CPU, memory, and network throughput depending).
As for "await all the way down", that seems like an issue to me. Typically await is associated to an external resource (DB call, HTTP request, etc.) that your application must wait on. If you await code that doesn't have external IO dependencies, you're creating overhead that isn't needed. It's possible to have multiple awaits in an async method chain, but awaiting some code that itself calls await but has no other external IO dependency is not good and will just add callback/compiler overhead.
Usually, the reasoning behind async/await goes the other way around:
For whatever reason, you decide that Func2 would be easier to write using await. So you simplify the method by adding the desired awaits, meaning you also have to change the method signature (it will now include the async keyword and a return type of Task or Task<T>).
Because the return type has changed, you can no longer call Func2 like you used to (var result = Func2();), so you're now required to change the calling method, Func1. The easiest way to adapt Func1 will often be to make it async too, and await Func2().
Then, for the same reason (changed signature), you will need to change all calls to Func1, and so on until you get to some kind of entry point (either a UI event handler, or your Main method, or something else).
So you don't start making the "outermost" method async and follow through to the "inner" (called) methods; you usually make things async while going in the opposite direction (from the "innermost" methods back to the calling ones). This other answer calls this idea "async all the way up".
"This async method lacks 'await' operators and will run synchronously" is what happens if you don't await an async method. To harness the benefits of an async method you must await it, turning the caller into an async method which can be awaited etc etc.
From the flow diagram you see that the async method returns a Task (a promise of work to be completed in the future) and yields control to it's caller. The caller can then get on with work not dependent on this result in the meantime. Clearly this needs to bubble up the call stack to find all of this gainful work that can be done without the result (In a UI app this work would include unblocking the UI, which is why it's async all the way up to the the event handler in the below example).
From my initial misreading. So you've found some async code that you need to call, is it worth the async await pattern spreading up your code:
I've heard a lot that the main problem with async-await is it's a much too easy syntax for what it actually does. Program flow gets complicated. I really like async-await, but unfortunately in most the async code I've seen it isn't worth it and is just needlessly ruining my call-stack.
A good thing to keep in mind is the 50ms rule.
"This is the rule that Microsoft followed with the WinRT APIs; anything taking less than 50ms is considered “fast” and close enough to “immediate” that they do not require an asynchronous API."
This is being used in the context of encouraging async-await. However, I think it equally should be applied to tell developers using async-await for essentially immediate functionality to cut it out.
In a UI based application async await provides a very succinct way to handle asynchronous calls resulting in UI updates. If the 'top level' handler from the UI is awaiting a result then there is potentially no real benefit in the whole chain down doing the same unless it makes sense to do so. A design goal of async await was to make async programming look more synchronous and continuous and not have callbacks scattered around etc - making async coding more assessable. It's not something you need to use everywhere arbitrarily.
A few posts on stack overflow have suggested the following:
Any async method where you have a single await expression awaiting a Task or Task < T >, right at the end of the method with no further processing, would be better off being written without using async/await.
Architecture for async/await
Await or Return
Is this advice just for particular circumstances? On a web server, isn't one of the main reasons to use async/await, being that while awaiting something like the UpdateDataAsync method below, the Thread will return to the ThreadPool, allowing the server to work on other requests?
Should SaveDataAsync await that DB update call given it's the last call in the method?
public async Task WorkWithDataAsync(Data data)
{
ManipulateData(data);
await SaveDataAsync(data);
await SendDataSomewhereAsync(data);
}
public async Task SaveDataAsync(Data data)
{
FixData(data);
await DBConnection.UpdateDataAsync(data);
}
Also, given you don't know where SaveDataAsync will be used, making it synchronous would hurt a method like WorkWithDataAsync would it not?
Removing the await and just returning the Task doesn't make the method synchronous. await is a tool that makes it easier to make a method asynchronous. It's not the only way to make a method asynchronous. It's there because it allows you to add continuations to task much more easily than you could without it, but in the method that you've shown you're not actually leveraging the await keyword to accomplish anything and as such you can remove it and have the code simply function identically.
(Note that technically the semantics of exceptions will have been slightly changed by removing async; thrown exceptions will be thrown from the method, not wrapped in the returned Task, if it matters to you. As far as any caller is concerned, this is the only observable difference.)
Writing these methods without the async-await keywords doesn't make them synchronous.
The idea is to return the task directly instead of having the overhead of generating the state machine.
The actual difference is about exception handling. An async method encapsulates exceptions inside the returned task while a simple task returning method doesn't.
If for example FixData throws an exception it will be captured in an async method but directly thrown in a simple task returning one. Both options would be equally asynchronous.