I wrote a small computer game where you can mine gold. The game is used to understand asynchronous programming with async and await. The loop menu offers three options: Mine gold, view evaluation, and exit.
The GoldMining method makes heavy use of the CPU. The probability to get one gram of gold during a mining is 1 in 10.000.000. Therefore it takes a long time until 1000g of gold are mined.
You start mining gold asynchronously from the loop menu. Then you can use option 2 (show evaluation) at any time to see the amount of gold you have mined so far.
Although the GoldMining method is very time consuming, the loop menu does not freeze. That's nice. However, I call the asynchronous method GoldMining without await. Now my question: Is this way of calling asynchronous methods to prevent the program from freezing a recommended approach?
//Evaluation contains the gold stock that was mined in total.
//The class definition is done at the very bottom.
Evaluation evaluation = new Evaluation();
await Main(evaluation);
static async Task Main(Evaluation evaluation){
string input="start";
while(input!="exit"){
Console.WriteLine("choose an option:");
Console.WriteLine("1 gold mining");
Console.WriteLine("2 show evaluation");
Console.WriteLine("3 exit.");
input=Console.ReadLine();
switch(input){
//Call GoldMining without await
case "1":GoldMining(evaluation);break;
case "2":Console.WriteLine(evaluation.gold);;break;
case "exit":input="exit"; break;
default:input="exit";break;
}
}
}
static async Task GoldMining(Evaluation evaluation){
Random rand= new Random();
int yield=0;
Console.WriteLine("Gold mining begins");
await Task.Run(() =>
{
while(yield<1000){
int chance =rand.Next(0,10000000);
if(chance==1){yield++;evaluation.gold++;}
} 2
});
Console.WriteLine("1000g Gold minded");
}
public class Evaluation{
public int gold{get;set;}
public Evaluation(){
this.gold=0;
}
}
The game is used to understand asynchronous programming with async and await... The GoldMining method makes heavy use of the CPU.
Asynchronous code is not a natural fit with CPU-bound methods. For CPU-bound methods, you want parallel code or multithreading.
If you want to learn asynchronous code in a more natural way, use an I/O-bound operation. E.g., an HTTP request to https://deelay.me/10000/https://google.com/.
Note that Task.Run is a form of multithreading (pushing work onto the thread pool). So your code is already using both multithreading and asynchrony - which is fine, but complicates things while learning.
However, I call the asynchronous method GoldMining without await. Now my question: Is this way of calling asynchronous methods to prevent the program from freezing a recommended approach?
No, certainly not. This is a kind of "fire and forget", which is dangerous in general. You almost always want to call await; if you do need to spin off a separate "top-level task", then you normally want to capture the task into a local variable and await it later. Otherwise, your app may exit before the operation is complete, and also you may not be aware of any exceptions that have happened.
I'm a bit irritated because I learned from a couple of Youtube videos that the big advantage of asynchronous programming is that the program doesn't freeze while it's handling a complex task.
You're currently writing a Console application. While Console apps are nice for learning most technologies, I believe using Console for learning async is not a good idea. Console apps can be asynchronous, but it's a very unusual environment for asynchronous applications. A much more natural environment is a client app (UI) or a server app (ASP.NET), both of which have framework-level support for asynchrony.
So, when the videos mention not "freezing", they're referring to how await (on a UI app) can keep the UI thread free to handle other messages. Since a Console app doesn't have a UI message loop, the same benefit doesn't apply there. You can build it, but it's way better IMO to learn proper async/await with either a UI app or an ASP.NET app first.
So, first of all your code is not thread safe. You need to use Interlocked.Increment(ref evaluation.gold) instead of evaluation.gold++ and volatile read (or even dummy Interlocked.CompareExchange, see this) at case "2". This may or may not matter, depending on whether your task scheduler is multithreaded or not (it is by default). Well, actually if your scheduler is single threaded then your code wouldn't work at all, due to an infinite loop (adding await Task.Yield(); inside the while loop in Main() would fix that). Either way, the rule of thumb is: always write a thread safe code when doing async.
Now my question: Is this way of calling asynchronous methods to prevent the program from freezing a recommended approach?
Yes, it is a good idea to spawn a background worker, in fact there's no other way to achieve that (I mean, you can spawn a thread instead of async task, but the idea is the same). And no, it is not a good idea to leave it without supervision. What if it fails? You have no option to react to it, even to log an error. What if GoldMining() is called multiple times? Maybe it is allowed, but without limit?
You could keep the result of calling GoldMining() around (without await) and check its status from time to time. You could keep it in a list and disallow too many. But perhaps a better approach would be to have a separate queue, a separate thread/async task that operates on it and also gracefuly handles all the errors. All of that wrapped into a single class.
Related
I have an async call (DoAsyncWork()), that I would like to start in a fire-and-forget way, i.e. I'm not interesting in its result and would like the calling thread to continue even before the async method is finished.
What is the proper way to do this? I need this in both, .NET Framework 4.6 as well as .NET Core 2, in case there are differences.
public async Task<MyResult> DoWorkAsync(){...}
public void StarterA(){
Task.Run(() => DoWorkAsync());
}
public void StarterB(){
Task.Run(async () => await DoWorkAsync());
}
Is it one of those two or something different/better?
//edit: Ideally without any extra libraries.
What is the proper way to do this?
First, you need to decide whether you really want fire-and-forget. In my experience, about 90% of people who ask for this actually don't want fire-and-forget; they want a background processing service.
Specifically, fire-and-forget means:
You don't care when the action completes.
You don't care if there are any exceptions when executing the action.
You don't care if the action completes at all.
So the real-world use cases for fire-and-forget are astoundingly small. An action like updating a server-side cache would be OK. Sending emails, generating documents, or anything business related is not OK, because you would (1) want the action to be completed, and (2) get notified if the action had an error.
The vast majority of the time, people don't want fire-and-forget at all; they want a background processing service. The proper way to build one of those is to add a reliable queue (e.g., Azure Queue / Amazon SQS, or even a database), and have an independent background process (e.g., Azure Function / Amazon Lambda / .NET Core BackgroundService / Win32 service) processing that queue. This is essentially what Hangfire provides (using a database for a queue, and running the background process in-proc in the ASP.NET process).
Is it one of those two or something different/better?
In the general case, there's a number of small behavior differences when eliding async and await. It's not something you would want to do "by default".
However, in this specific case - where the async lambda is only calling a single method - eliding async and await is fine.
It depends on what you mean by proper :)
For instance: are you interested in the exceptions being thrown in your "fire and forget" calls? If not, than this is sort of fine. Though what you might need to think about is in what environment the task lives.
For instance, if this is a asp.net application and you do this inside the lifetime of a thread instantiated due to a call to a .aspx or .svc. The Task becomes a background thread of that (foreground)thread. The foreground thread might get cleaned up by the application pool before your "fire and forget" task is completed.
So also think about in which thread your tasks live.
I think this article gives you some useful information on that:
https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
Also note that if you do not return a value in your Tasks, a task will not return exception info. Source for that is the ref book for microsoft exam 70-483
There is probably a free version of that online somewhere ;P https://www.amazon.com/Exam-Ref-70-483-Programming-C/dp/0735676828
Maybe useful to know is that if your have an async method being called by a non-async and you wish to know its result. You can use .GetAwaiter().GetResult().
Also I think it is important to note the difference between async and multi-threading.
Async is only useful if there are operations that use other parts of a computer that is not the CPU. So things like networking or I/O operations. Using async then tells the system to go ahead and use CPU power somewhere else instead of "blocking" that thread in the CPU for just waiting for a response.
multi-threading is the allocation of operations on different threads in a CPU (for instance, creating a task which creates a background thread of the foreground thread... foreground threads being the threads that make up your application, they are primary, background threads exist linked to foreground threads. If you close the linked foreground thread, the background thread closes as well)
This allows the CPU to work on different tasks at the same time.
Combining these two makes sure the CPU does not get blocked up on just 4 threads if it is a 4 thread CPU. But can open more while it waits for async tasks that are waiting for I/O operations.
I hope this gives your the information needed to do, what ever it is you are doing :)
I'm making app with using XF pcl. Even I launched my app on the store already, I'm still newbie in c# world. I'm having a trouble especially using a Thread.
In XF/iOS, I faced after I launched app and took a while(longer than a day), all of Task.Run() of my code does not start new thread. A person advised me if there is a chance that I'm starting many thread and somehow they are not terminated. So new thread's not started.
So I searched my project and I have Task.Run at about 20 places in my code.
I used it when I call 'async Task' method even it background thread is not necessary.
So, I'm going to change it by using 'async void'. But I already changed it like this. and no problem.
Let's say AAAAA() is a 'async Task' method from some nuget library I'm using. So
I can not change method.
void Something()
{
...
Task.Run(async () => await XXXXX.AAAAA());
...
}
to
async void Something()
{
...
await XXXXX.AAAAA();
...
}
But sometimes, I faced that I can't change a method to async easily. So I'm going to change like this at that time.
void Something()
{
...
AA();
...
}
async void AA()
{
await XXXXX.AAAAA();
}
Is this OK unless background thread is not necessary?
I ask this question because I watched lots of videos that saying not to use "Async void".
I wonder if I could use like this if there seems no problem.
Any advice will help me.
Thanks.
Don't do async void. There are several worst practices about it.
Instead, try to solve your threading problems from the root with a good approach to asynchronous programming.
1. Define your task boundaries
Do not just "fire and forget". Expect your task to end and release resources. There are good reasons not to do Task.Run(...) and forget about it.
Async methods exist for a reason. They return in the Future (to quote the Java world). If you fire too many Async task that take long time to complete or get stuck in a loop, you drain your system resources and may end up unable to spawn new tasks.
So analyze your prolem, don't just run random methods from random packages. Design your workflow and identify parallelisms.
A simple straightforward solution is to Task.Run(()=>).Wait(). This destroys all kinds of parallelism but will constrain the resources and, most importantly, adheres with your synchronous programming.
2. A Task is not a Thread
While I discourage the unbounded/uncontrolled use of threads, the truth is that Task.Run(...) won't necessarily spawn new threads. It may not actually do anything under some circumstances.
For example I was forced to do this to force starting a new thread
Task.Factory.StartNew(()=>..., cancellationToken: tokenSource.Token, creationOptions:
TaskCreationOptions.LongRunning, scheduler: TaskScheduler.Default);
TaskCreationOptions.LongRunning tells the Task factory to use an available separate thread. Normally Task.Run runs on the same current thread by exploiting VM waits to run code from other tasks, so as to perform a lightweight context switch. If your synchronous code blocks in a synchronous way the runtime may not give control to other tasks.
3. TPL is made for 2 things
One is responsiveness. If your application is completely asynchronous, then a good use of the TPL leaves your UI thread responsive over waits, e.g. if you click on a button you won't see the whole window greyed and "stuck". This behaviour was introduced by Microsoft to help developers that are unfriendly with proper multithread programming
The other is I/O optimization. If you need to download 5 files, parse a text file from disk and store a bunch of rows in the database you can fire 7 task that leverage the I/O wait times of each task (e.g. SSL handshake, disk buffering, SQL response wait) so that the 7 tasks will reasonably complete by the time of the longest.
If you just invoke asynchronous methods because you found them on your NuGet library you are just doing it wrong, as you may need to invoke the corresponding synchronous version
Summarizing
Your question reveals a lack of understanding of parallel programming. In fact you said you are new to C#. Welcome to the world of .NET.
Parallel programming is not easy, and without a knowledge of your application design it is impossible to help you in a single short answer. You need to take several examples and/or ask questions about specific best practice for some parts of your application by posting real or simil-real code.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I'm trying to wrap my head around all of the Async stuff that's been added into the .NET framework with the more recent versions. I understand some of it, but to be honest, personally I don't think it makes writing asynchronous code easier. I find it rather confusing most of the time and actually harder to read than the more conventional approaches that we used before the advent of async/await.
Anyway, my question is a simple one. I see a lot of code like this:
var stream = await file.readAsStreamAsync()
What's going on here? Isn't this equivalent to just calling the blocking variant of the method, i.e.
var stream = file.readAsStream()
If so, what's the point in using it here like this? It doesn't make the code any easier to read so please tell me what I am missing.
The result of both calls is the same.
The difference is that var stream = file.readAsStream() will block the calling thread until the operation completes.
If the call was made in a GUI app from the UI thread, the application will freeze until the IO completes.
If the call was made in a server application, the blocked thread will not be able to handle other incoming requests. The thread pool will have to create a new thread to 'replace' the blocked one, which is expensive. Scalability will suffer.
On the other hand, var stream = await file.readAsStreamAsync() will not block any thread. The UI thread in a GUI application can keep the application responding, a worker thread in a server application can handle other requests.
When the async operation completes, the OS will notify the thread pool and the rest of the method will be executed.
To make all this 'magic' possible, a method with async/await will be compiled into a state machine. Async/await allows to make complicated asynchronous code look as simple as synchronous one.
It makes writing asynchronous code enormously easier. As you noted in your own question, it looks as if you were writing the synchronous variant - but it's actually asynchronous.
To understand this, you need to really know what asynchronous and synchronous means. The meaning is really simple - synchronous means in a sequence, one after another. Asynchronous means out of sequence. But that's not the whole picture here - the two words are pretty much useless on their own, most of their meaning comes from context. You need to ask: synchronous with respect to what, exactly?
Let's say you have a Winforms application that needs to read a file. In the button click, you do a File.ReadAllText, and put the results in some textbox - all fine and dandy. The I/O operation is synchronous with respect to your UI - the UI can do nothing while you wait for the I/O operation to complete. Now, the customers start complaining that the UI seems hung for seconds at a time when it reads the file - and Windows flags the application as "Not responding". So you decide to delegate the file reading to a background worker - for example, using BackgroundWorker, or Thread. Now your I/O operation is asynchronous with respect to your UI and everyone is happy - all you had to do is extract your work and run it in its own thread, yay.
Now, this is actually perfectly fine - as long as you're only really doing one such asynchronous operation at a time. However, it does mean you have to explicitly define where the UI thread boundaries are - you need to handle the proper synchronization. Sure, this is pretty simple in Winforms, since you can just use Invoke to marshal UI work back to the UI thread - but what if you need to interact with the UI repeatedly, while doing your background work? Sure, if you just want to publish results continuously, you're fine with the BackgroundWorkers ReportProgress - but what if you also want to handle user input?
The beauty of await is that you can easily manage when you're on a background thread, and when you're on a synchronization context (such as the windows forms UI thread):
string line;
while ((line = await streamReader.ReadLineAsync()) != null)
{
if (line.StartsWith("ERROR:")) tbxLog.AppendLine(line);
if (line.StartsWith("CRITICAL:"))
{
if (MessageBox.Show(line + "\r\n" + "Do you want to continue?",
"Critical error", MessageBoxButtons.YesNo) == DialogResult.No)
{
return;
}
}
await httpClient.PostAsync(...);
}
This is wonderful - you're basically writing synchronous code as usual, but it's still asynchronous with respect to the UI thread. And the error handling is again exactly the same as with any synchronous code - using, try-finally and friends all work great.
Okay, so you don't need to sprinkle BeginInvoke here and there, what's the big deal? The real big deal is that, without any effort on your part, you actually started using the real asynchronous APIs for all those I/O operations. The thing is, there aren't really any synchronous I/O operations as far as the OS is concerned - when you do that "synchronous" File.ReadAllText, the OS simply posts an asynchronous I/O request, and then blocks your thread until the response comes back. As should be evident, the thread is wasted doing nothing in the meantime - it still uses system resources, it adds a tiny amount of work for the scheduler etc.
Again, in a typical client application, this isn't a big deal. The user doesn't care whether you have one thread or two - the difference isn't really that big. Servers are a different beast entirely, though; where a typical client only has one or two I/O operations at the same time, you want your server to handle thousands! On a typical 32-bit system, you could only fit about 2000 threads with default stacksize in your process - not because of the physical memory requirements, but just by exhausting the virtual address space. 64-bit processes are not as limited, but there's still the thing that starting up new threads and destroying them is rather pricy, and you are now adding considerable work to the OS thread scheduler - just to keep those threads waiting.
But the await-based code doesn't have this problem. It only takes up a thread when it's doing CPU work - waiting on an I/O operation to complete is not CPU work. So you issue that asynchronous I/O request, and your thread goes back to the thread pool. When the response comes, another thread is taken from the thread pool. Suddenly, instead of using thousands of threads, your server is only using a couple (usually about two per CPU core). The memory requirements are lower, the multi-threading overheads are significantly lowered, and your total throughput increases quite a bit.
So - in a client application, await is only really a thing of convenience. In any larger server application, it's a necessity - because suddenly your "start a new thread" approach simply doesn't scale. And the alternative to using await are all those old-school asynchronous APIs, which handle nothing like synchronous code, and where handling errors is very tedious and tricky.
var stream = await file.readAsStreamAsync();
DoStuff(stream);
is conceptually more like
file.readAsStreamAsync(stream => {
DoStuff(stream);
});
where the lambda is automatically called when the stream has been fully read. You can see this is quite different from the blocking code.
If you're building a UI application for example, and implementing a button handler:
private async void HandleClick(object sender, EventArgs e)
{
ShowProgressIndicator();
var response = await GetStuffFromTheWebAsync();
DoStuff(response);
HideProgressIndicator();
}
This is drastically different from the similar synchronous code:
private void HandleClick(object sender, EventArgs e)
{
ShowProgressIndicator();
var response = GetStuffFromTheWeb();
DoStuff(response);
HideProgressIndicator();
}
Because in the second code the UI will lock up and you'll never see the progress indicator (or at best it'll flash briefly) since the UI thread will be blocked until the entire click handler is completed. In the first code the progress indicator shows and then the UI thread gets to run again while the web call happens in the background, and then when the web call completes the DoStuff(response); HideProgressIndicator(); code gets scheduled on the UI thread and it nicely finishes its work and hides the progress indicator.
What's going on here? Isn't this equivalent to just calling the
blocking variant of the method, i.e.
No, it is not a blocking call. This is a syntactic sugar that the compiler uses to create a state machine, which on the runtime will be used to execute your code asynchronously.
It makes your code more readable and almost similar to code that runs synchronously.
It looks like you're missing what is all this async / await concept is about.
Keyword async let compiler knows that method may need to perform some asynchronous operations and therefore it shouldn't be executed in normal way as any other method, instead it should be treated as state machine. This indicates that compiler will first execute only part of method (let's call it Part 1), and then start some asynchronous operation on other thread releasing the calling thread. Compiler also will schedule Part 2 to execute on first available thread from the ThreadPool. If asynchronous operation is not marked with keyword await then its not been awaited and calling thread continues to run till method is finished. In most cases this is not desirable. That's when we need to use keyword await.
So typical scenario is :
Thread 1 enters async method and executes code Part1 ->
Thread 1 starts async operation ->
Thread 1 is released, operation is underway Part2 is scheduled in TP ->
Some Thread (most likely same Thread 1 is its free) continues to run method till its end (Part2) ->
Probably this question has already been made, but I never found a definitive answer. Let's say that I have a Web API 2.0 Application hosted on IIS. I think I understand that best practice (to prevent deadlocks on client) is always use async methods from the GUI event to the HttpClient calls. And this is good and it works. But what is the best practice in case I had client application that does not have a GUI (e.g. Window Service, Console Application) but only synchronous methods from which to make the call? In this case, I use the following logic:
void MySyncMethodOnMyWindowServiceApp()
{
list = GetDataAsync().Result().ToObject<List<MyClass>>();
}
async Task<Jarray> GetDataAsync()
{
list = await Client.GetAsync(<...>).ConfigureAwait(false);
return await response.Content.ReadAsAsync<JArray>().ConfigureAwait(false);
}
But unfortunately this can still cause deadlocks on client that occur at random times on random machines.
The client app stops at this point and never returns:
list = await Client.GetAsync(<...>).ConfigureAwait(false);
If it's something that can be run in the background and isn't forced to be synchronous, try wrapping the code (that calls the async method) in a Task.Run(). I'm not sure that'll solve a "deadlock" problem (if it's something out of sync, that's another issue), but if you want to benefit from async/await, if you don't have async all the way down, I'm not sure there's a benefit unless you run it in a background thread. I had a case where adding Task.Run() in a few places (in my case, from an MVC controller which I changed to be async) and calling async methods not only improved performance slightly, but it improved reliability (not sure that it was a "deadlock" but seemed like something similar) under heavier load.
You will find that using Task.Run() is regarded by some as a bad way to do it, but I really couldn't see a better way to do it in my situation, and it really did seem to be an improvement. Perhaps this is one of those things where there's the ideal way to do it vs. the way to make it work in the imperfect situation that you're in. :-)
[Updated due to requests for code]
So, as someone else posted, you should do "async all the way down". In my case, my data wasn't async, but my UI was. So, I went async down as far as I could, then I wrapped my data calls with Task.Run in such as way that it made sense. That's the trick, I think, to figure out if it makes sense that things can run in parallel, otherwise, you're just being synchronous (if you use async and immediately resolve it, forcing it to wait for the answer). I had a number of reads that I could perform in parallel.
In the above example, I think you have to async up as far as makes sense, and then at some point, determine where you can spin off a t hread and perform the operation independent of the other code. Let's say you have an operation that saves data, but you don't really need to wait for a response -- you're saving it and you're done. The only thing you might have to watch out for is not to close the program without waiting for that thread/task to finish. Where it makes sense in your code is up to you.
Syntax is pretty easy. I took existing code, changed the controller to an async returning a Task of my class that was formerly being returned.
var myTask = Task.Run(() =>
{
//...some code that can run independently.... In my case, loading data
});
// ...other code that can run at the same time as the above....
await Task.WhenAll(myTask, otherTask);
//..or...
await myTask;
//At this point, the result is available from the task
myDataValue = myTask.Result;
See MSDN for probably better examples:
https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
[Update 2, more relevant for the original question]
Let's say that your data read is an async method.
private async Task<MyClass> Read()
You can call it, save the task, and await on it when ready:
var runTask = Read();
//... do other code that can run in parallel
await runTask;
So, for this purpose, calling async code, which is what the original poster is requesting, I don't think you need Task.Run(), although I don't think you can use "await" unless you're an async method -- you'll need an alternate syntax for Wait.
The trick is that without having some code to run in parallel, there's little point in it, so thinking about multi-threading is still the point.
Using Task<T>.Result is the equivalent of Wait which will perform a synchronous block on the thread. Having async methods on the WebApi and then having all the callers synchronously blocking them effectively makes the WebApi method synchronous. Under load you will deadlock if the number of simultaneous Waits exceeds the server/app thread pool.
So remember the rule of thumb "async all the way down". You want the long running task (getting a collection of List) to be async. If the calling method must be sync you want to make that conversion from async to sync (using either Result or Wait) as close to the "ground" as possible. Keep they long running process async and have the sync portion as short as possible. That will greatly reduce the length of time that threads are blocked.
So for example you can do something like this.
void MySyncMethodOnMyWindowServiceApp()
{
List<MyClass> myClasses = GetMyClassCollectionAsync().Result;
}
Task<List<MyClass>> GetMyListCollectionAsync()
{
var data = await GetDataAsync(); // <- long running call to remote WebApi?
return data.ToObject<List<MyClass>>();
}
The key part is the long running task remains async and not blocked because await is used.
Also don't confuse the responsiveness with scalability. Both are valid reasons for async. Yes responsiveness is a reason for using async (to avoid blocking on the UI thread). You are correct this wouldn't apply to a back end service however this isn't why async is used on a WebApi. The WebApi is also a non GUI back end process. If the only advantage of async code was responsiveness of the UI layer then WebApi would be sync code from start to finish. The other reason for using async is scalability (avoiding deadlocks) and this is the reason why WebApi calls are plumbed async. Keeping the long running processes async helps IIS make more efficient use of a limited number of threads. By default there are only 12 worker threads per core. This can be raised but that isn't a magic bullet either as threads are relatively expensive (about 1MB overhead per thread). await allows you to do more with less. More concurrent long running processes on less threads before a deadlock occurs.
The problem you are having with deadlocks must stem from something else. Your use of ConfigureAwait(false) prevents deadlocks here. Solve the bug and you are fine.
See Should we switch to use async I/O by default? to which the answer is "no". You should decide on a case by case basis and choose async when the benefits outweigh the costs. It is important to understand that async IO has a productivity cost associated with it. In non-GUI scenarios only a few targeted scenarios derive any benefit at all from async IO. The benefits can be enormous, though, but only in those cases.
Here's another helpful post: https://stackoverflow.com/a/25087273/122718
I've grasped the concept of async await and have been using it sporadically, but do have a couple questions regarding best practices.
is it ok to use await in a while(condition) loop to keep fetching data that may be present, until the while condition changes, e.g. stopProcessingMessages = false.
in an application such as winforms, while UI runs on it's thread, using async/await on an operation such as a button click is fairly trivial, but what about if I would like to enforce asynchronously throughout an entire console application, or even a windows service. what is the best practice to initially kick off that first await task, would that be Task.Run (() => ... )?
I hope I am making sense in my 2nd question. I want to make the most of async and utilize it to it's full extent, but just need to understand how to kick off the initial asynchronous operation before it bubbles down to all other asynchronous functions.
apologies for not using the proper code blocks I am on the train using my smartphone.
I've grasped the concept of async await and have been using it sporadically, but do have a couple questions regarding best practices.
I have an intro to async/await blog post that goes into more detail than most intros and also introduces several best practices.
is it ok to use await in a while(condition) loop to keep fetching data that may be present, until the while condition changes, e.g. stopProcessingMessages = false.
You want to avoid tight loops. So the while (condition) GetDataIfPresent(); is going to consume a lot of CPU.
Alternatively, you could use an async method that returned null (or whatever) if stopProcessingMessages is true. In this case, your code would be while (true), and a more TAP-like solution would be to use CancellationSource instead of a flag.
Also take a look at TPL Dataflow; it sounds like it may be useful for your kind of situation.
console application, or even a windows service. what is the best practice to initially kick off that first await task
For console apps, you could Wait on the top-level task. This is an acceptable exception to the usual guideline (which is to await instead of Wait). Waiting will burn a thread for the duration of the console app, but that's usually not important enough to warrant a more complex solution. If you do want to install a single-threaded context for your console app, you could use AsyncContext.Run from my AsyncEx library.
For Win32 services, you usually do need to start your own thread. You can use Task.Run for this (if you want a multithreaded context), or AsyncContextThread from AsyncEx (if you want a single-threaded context).
Good morning,
I would rather use a regular task with the TaskCreationOption set to 'LongRunning' in your first scenario than the async/await pattern.
This way your whole while block would be executed in one long running task. When using await inside each while loop you would start a new task with every loop - would work, but it's maybe not so optimal ;-)
Regarding your second question, I'm sorry but I don't get your point.
Hope this helps.
It is not ok to use a loop to keep fething data that may be present..
You can create an async call that upon completion will automaticlly invoke a callback method.. the "waiting" phase in that case will happen in the OS mechanisms which treat this waiting phase in optimum way to the OS being used.
Take a look here for further study of the subject:
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx