What's the new C# await feature do? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Can anyone explain what the await function does?

They just talked about this at PDC yesterday!
Await is used in conjunction with Tasks (parallel programming) in .NET. It's a keyword being introduced in the next version of .NET. It more or less lets you "pause" the execution of a method to wait for the Task to complete execution. Here's a brief example:
//create and run a new task
Task<DataTable> dataTask = new Task<DataTable>(SomeCrazyDatabaseOperation);
//run some other code immediately after this task is started and running
ShowLoaderControl();
StartStoryboard();
//this will actually "pause" the code execution until the task completes. It doesn't lock the thread, but rather waits for the result, similar to an async callback
// please so also note, that the task needs to be started before it can be awaited. Otherwise it will never return
dataTask.Start();
DataTable table = await dataTask;
//Now we can perform operations on the Task result, as if we're executing code after the async operation completed
listBoxControl.DataContext = table;
StopStoryboard();
HideLoaderControl();

Basically, the async and await keywords allow you to specify that execution of a method should stop at all usages of await, which mark asynchronous method calls, and then resume once the asynchronous operation is complete. This allows you to call a method in an app's main thread and handle complex work asynchronously, without the need to explicitly define threads and joins or blocking the app's main thread.
Think of it as being somewhat similar to a yield return statement in a method producing an IEnumerable. When the runtime hits the yield, it will basically save the method's current state, and return the value or reference being yielded. The next time IEnumerator.MoveNext() is called on the return object (which is generated internally by the runtime), the method's old state is restored to the stack and execution continues with the next line after the yield return as if we'd never left the method. Without this keyword, an IEnumerator type must be custom-defined to store state and handle the iteration requests, with methods that can become VERY complex indeed.
Similarly, a method marked as async must have at least one await. On an await, the runtime will save the current thread's state and call stack, make the asynchronous call, and unwind back to the runtime's message loop to handle the next message and keep the app responsive. When the asynchronous operation is complete, at the next scheduling opportunity, the call stack to up the async operation is pushed back in and continued as if the call was synchronous.
So, these two new keywords basically simplify the coding of asynchronous processes, much like yield return simplified the generation of custom enumerables. With a couple keywords and a little background knowledge, you can skip all the confusing and often error-prone details of a traditional asynchronous pattern. This will be INVALUABLE in pretty much any event-driven GUI app like Winforms, WPF of Silverlight.

The currently accepted answer is misleading.
await is not pausing anything.
First of all it can be used only in methods or lambdas marked as async and returning Task or void if you don't care having Task instance running in this method.
Here is an illustration:
internal class Program
{
private static void Main(string[] args)
{
var task = DoWork();
Console.WriteLine("Task status: " + task.Status);
Console.WriteLine("Waiting for ENTER");
Console.ReadLine();
}
private static async Task DoWork()
{
Console.WriteLine("Entered DoWork(). Sleeping 3");
// imitating time consuming code
// in a real-world app this should be inside task,
// so method returns fast
Thread.Sleep(3000);
await Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("async task iteration " + i);
// imitating time consuming code
Thread.Sleep(1000);
}
});
Console.WriteLine("Exiting DoWork()");
}
}
Output:
Entered DoWork(). Sleeping 3
async task iteration 0
Task status: WaitingForActivation
Waiting for ENTER
async task iteration 1
async task iteration 2
async task iteration 3
async task iteration 4
async task iteration 5
async task iteration 6
async task iteration 7
async task iteration 8
async task iteration 9
Exiting DoWork()

For anyone new to asynchronous programming in .NET, here's a (totally fake) analogy in a scenario you may be more familiar with - AJAX calls using JavaScript/jQuery. A simple jQuery AJAX post looks like this:
$.post(url, values, function(data) {
// AJAX call completed, do something with returned data here
});
The reason we process the results in a callback function is so we don't block the current thread while waiting for the AJAX call to return. Only when the response is ready will the callback get fired, freeing the current thread to do other things in the mean time.
Now, if JavaScript supported the await keyword (which of course it doesn't (yet!)), you could achieve the same with this:
var data = await $.post(url, values);
// AJAX call completed, do something with returned data here
That's a lot cleaner, but it sure looks like we introduced synchronous, blocking code. But the (fake) JavaScript compiler would have taken everything after await and wired it into a callback, so at runtime the second example would behave just like the first.
It may not seem like it's saving you much work, but when it comes to things like exception handling and synchronization contexts, the compiler is actually doing a lot of heavy lifting for you. For more, I'd recommend the FAQs followed by Stephen Cleary's blog series.

If I had to implement it in Java it would look some thing like this:
/**
* #author Ilya Gazman
*/
public abstract class SynchronizedTask{
private ArrayList<Runnable> listeners = new ArrayList<Runnable>();
private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 6, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1000));
public final void await(Runnable listener){
synchronized (this) {
listeners.add(listener);
}
}
public void excecute(){
onExcecute();
for (int i = listeners.size() - 1; i >= 0; i--) {
Runnable runnable;
synchronized (this) {
runnable = listeners.remove(i);
}
threadPoolExecutor.execute(runnable);
}
}
protected abstract void onExcecute();
}
Your application would use it like this:
public class Test{
private Job job = new Job();
public Test() {
craeteSomeJobToRunInBackground();
methode1();
methode2();
}
private void methode1(){
System.out.println("Running methode 1");
job.await(new Runnable() {
#Override
public void run() {
System.out.println("Continue to running methode 1");
}
});
}
private void methode2(){
System.out.println("Running methode 2");
}
private void craeteSomeJobToRunInBackground() {
new Thread(new Runnable() {
#Override
public void run() {
job.excecute();
}
}).start();
}
private class Job extends SynchronizedTask{
#Override
protected void onExcecute() {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Job is done");
}
}
}

Related

Windows form application timertick problem

I used hold and release timer tick with modbus protocol.So It reads every second
Timer Interval : 1000
Enabled : True
I'm having a freezing problem. How can I fix it?
Please Help Me.
private void Timer1_Tick(object sender, EventArgs e)
{
ModBus1.Send_Device(Read, temperatureStartAddress, (ushort)TemperatureValueQnty, temperatureValue);
Thread.Sleep(250);
ModBus1.Send_Device(Read, temperatureStartAddress, (ushort)TemperatureValueQnty, temperatureValue);
Thread.Sleep(50);
if (SettingsTab.Enabled == true)
{
moduleTextBox.Text = temperatureValue[0].ToString();
moduleTextBox2.Text = temperatureValue[1].ToString();
moduleTextBox3.Text = temperatureValue[2].ToString();
moduleTextBox4.Text = temperatureValue[3].ToString();
moduleTextBox5.Text = temperatureValue[4].ToString();
moduleTextBox6.Text = temperatureValue[5].ToString();
moduleTextBox7.Text = temperatureValue[6].ToString();
moduleTextBox8.Text = temperatureValue[7].ToString();
moduleTextBox9.Text = temperatureValue[8].ToString();
moduleTextBox10.Text = temperatureValue[9].ToString();
moduleTextBox11.Text = temperatureValue[10].ToString();
moduleTextBox12.Text = temperatureValue[11].ToString();
}
}
After reading the comments, the real question is:
Method ModBus1.Send has a parameter temperatureValue which is an int[]. I want to convert the filled data to a List<double>
I wonder how you know how long you should make your array of integers, but let's assume you do know the length:
int temperatureValueCount = ...; // expected number of temperature values
int[] temperatureValues = new int[temperatureValueCount];
ModBus1.Send_Device(Read, temperatureStartAddress,
(ushort)TemperatureValueQnty,
temperatureValues);
// temperatureValues is now filled with integers
// convert this to a List<double> using LINQ:
List<double> returnValue = temperatureValues.Cast<double>().ToList();
Or if you don't like LINQ:
List<double> returnValue = new List<double>(temperatureValues.Length);
foreach (int temperatureValue in temperatureValues)
returnValue.Add((double)temperatureValue);
Back to the original question
I'm having a freezing problem.
If you use your user interface thread to do some lengthy processing, then during this processing your user interface is not responsive.
Nowadays there are two often used methods to prevent this:
Start a different thread to do this lengthy calculation
If your calculation is mostly waiting idly for another process, like waiting for a file to be written, a database query to be executed, or waiting for information of the internet, or in your case: waiting until some time has passed: use async-await.
async await is only useful if your thread will be waiting idly for something else.
If your thread has to do some heavy calculations, so if it will be really busy, consider to start a different thread to do the calculations. This way your user interface thread will be free to handle operator requests.
If you are not familiar with async-await, this interview with Eric Lippert really helped me to understand async-await. Search somewhere in the middle for async await.
Eric Lippert compares async await with a cook who has to make breakfast. He could start boiling water for the tea, wait until the water boils and make the tea. Then he puts bread in the toaster and wait idly until the bread is toasted. After that he boils some eggs, and waits idly until the eggs are finished.
You see all the idly waits for other processes. It would be much more efficient to put on the kettle for the tea, start toasting the bread and boiling the eggs. The task that finishes first continues first.
Async-await is similar: instead of waiting until the file has been written, or the database query returns data, your thread looks around to see if he can do something else, like responding to user input.
To use async await you'll have to change your code slightly.
Every method that uses async-await, must be declared async
Every async method should return Task<TResult> instead of TResult and Task instead of void
Only exception: event handlers (like button clicked), they return void.
Inside your async method, call other async methods and await for them to finish. In fact, your compiler will warn you if you forget to await.
If you don't need the results of the await immediately, don't await yet, continue processing until you need the result of the async method.
Make sure that every task has been awaited before you return from the async method, even if you don't need the result. If you don't await, you don't know when the task is finished, and thus will never know if you can safely destruct your class.
Just a convention: async method names have Async postfix. So you can keep them next to the non-async version: TextWriter.Write and TextWriter.WriteAsync.
.
async Task<int> CalculateOrderTotalAsync(int orderId)
{
Task<int> taskFetchOrderTotal = dbContext.OrderLines
.Where(orderLine => orderLine.OrderId == orderId)
.Select(orderLine => orderLine.Price)
.SumAsync();
// because you didn't await, you are free to do some other processing:
DoSomethingElse();
// now you need the result of the database query:
int orderTotal = await taskFetchOrderTotal();
return orderTotal;
}
While the database management system is executing the query, your thread is free to do something else. When it needs the results, it starts awaiting. If the database query is finished, it continues. If not, the thread doesn't wait idly, but goes up the call stack to execute other statements, until it sees an await, goes up the call stack again, etc.
Quite often, your task has noting else to do. In that case you'll see the await immediately before the call:
async Task SaveTextAsync(string fileName, string text)
{
using (var textWriter = File.CreateText(fileName))
{
await textWriter.WriteLineAsync(text);
}
}
Back to your question
Your thread is mostly waiting idly, in your Sleep methods. There is an async method to await some time: Task.Delay. If you use that in an async method your UI will be responsive.
private async Task<List<double> ReadTemperatureValuesAsync()
{
List<double> temperaturValues = new List<double>();
// tell the modbus to start reading the temperatures:
ModBus1.Send_Device(Read, temperatureStartAddress, (ushort)TemperatureValueQnty, temperatureValues);
// await 250 msec. The UI will be responsive
await Task.Delay(TimeSpan.FromSeconds(0.250));
// communicate with the modbus again. and await again:
ModBus1.Send_Device(Read, temperatureStartAddress, (ushort)TemperatureValueQnty, temperatureValues);
await Task.Delay(TimeSpan.FromMiliSeconds(50);
return temperatureValues;
}
You need a method to Display the Temperature values. This procedure has no idly wait. So no await needed:
private void DisplayMeasuredTemperatures(List<double> measuredTemperatures)
{
moduleTextBox.Text = temperatureValue[0].ToString();
moduleTextBox2.Text = temperatureValue[1].ToString();
...
}
Put it all together: async Measure and display the results:
private async Task MeasureAndDisplayTemperaturesAsync()
{
List<double> measuredTemperatures = await this.ReadTemperatureValuesAsync();
if (SettingsTab.Enabled)
{
DisplayMeasuredTemperatures(measuredTemperatures);
}
}
Finally your timer tick method. This is an event handler: return void instead of Task:
private async void Timer1_Tick(object sender, EventArgs e)
{
await MeasureAndDisplayTemperaturesAsync();
}
If you want to call it after a button click:
private async void Button1_Click(object sender, EventArgs e)
{
await MeasureAndDisplayTemperaturesAsync();
}
Long calculations
If your method doesn't have to wait for another process, but has some long calculations to do, think of starting a Task, and await for it to finish.
private int SomeLongCalculations(Customer customer)
{
int result = 0;
for (long i=0; i<10000000000000000000000; ++i)
{
... // something with Customer and i
}
return result;
}
private async Task<int> CalculateAsync(Customer customer)
{
int calculationResult = await Task.Run(() => this.SomeLongCalculations(customer);
return calculationResult;
}

Asynchronous C# [duplicate]

This question already has answers here:
How and when to use ‘async’ and ‘await’
(25 answers)
Call asynchronous method in constructor?
(15 answers)
How Async and Await works
(4 answers)
Closed 4 years ago.
I have a question about both keywords (Async and Await)
Their main goal is to make more than one method to be done at the same time as i understood, so for example if i'm going to do a long task which will prevent the main task from being executed in that case i have to use (Async and Await).
But when I tried it in two different programs that do the same thing i found that the execution is the same w/o using (Async and Await)
first one
class Async
{
public Async()
{
main();
}
public async void main()
{
Console.WriteLine("Main Thread....");
await SlowTask();
Console.WriteLine("Back To Main Thread");
}
public async Task SlowTask()
{
Console.WriteLine("Useless Thread....");
for (int i = 0; i < 1000000; i++)
{
// TODO
}
Console.WriteLine("Finished Useless Thread....");
}
}
and the second
class NoAsync
{
public NoAsync()
{
main();
}
public void main()
{
Console.WriteLine("Main Thread....");
SlowTask();
Console.WriteLine("Back To Main Thread");
}
public void SlowTask()
{
Console.WriteLine("Useless Thread....");
for (int i = 0; i < 1000000; i++)
{
// TODO
}
Console.WriteLine("Finished Useless Thread....");
}
}
the execution of both are exactly the same, from what i understood that when using (Async and Await) both main and SlowTask will execute at the same time without waiting for one to end so the other start to execute but that doesn't happen.
What's wrong i've made or i'm miss-understanding Asynchronous in c# ?
Kind regards.
I'd expect the execution of both to be the same. The issue is the latter, you have a misunderstanding of async in C#.
In short, when you await something in an async method, that thread is freed up to go do other stuff, until the awaited task finishes. But the program does not continue executing the next line until the awaited method completes. That would be bananas. You're thinking more of a background worker.
This can be handy, for example, when you are doing I/O and want a thread to be available to field http requests in the meantime. There is an abundance of reading material on this already. Here is a more in-depth answer
The execution should be exactly the same, they are logically consistent programs. There's likely not even a single task switch given your whole program is merely incrementing a counter variable.

Combining CPU-bound and IO-bound work in async method

There is such application:
static void Main(string[] args)
{
HandleRequests(10).Wait();
HandleRequests(50).Wait();
HandleRequests(100).Wait();
HandleRequests(1000).Wait();
Console.ReadKey();
}
private static async Task IoBoundWork()
{
await Task.Delay(100);
}
private static void CpuBoundWork()
{
Thread.Sleep(100);
}
private static async Task HandleRequest()
{
CpuBoundWork();
await IoBoundWork();
}
private static async Task HandleRequests(int numberOfRequests)
{
var sw = Stopwatch.StartNew();
var tasks = new List<Task>();
for (int i = 0; i < numberOfRequests; i++)
{
tasks.Add(HandleRequest());
}
await Task.WhenAll(tasks.ToArray());
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
Below the output of this app:
From my perspective having CPU-bound and IO-bound parts in one method it is quite regular situation, e.g. parsing/archiving/serialization of some object and saving that to the disk, so it should probably work well. However in the implementation above it works very slow. Could you please help me to understand why?
If we wrap the body of CpuBoundWork() in Task it significantly improve performance:
private static async Task CpuBoundWork()
{
await Task.Run(() => Thread.Sleep(100));
}
private static async Task HandleRequest()
{
await CpuBoundWork();
await IoBoundWork();
}
Why it works so slow without Task.Run? Why we can see performance boost after adding Task.Run? Should we always use such approach in similar methods?
for (int i = 0; i < numberOfRequests; i++)
{
tasks.Add(HandleRequest());
}
The returned task is created at the first await in the HandleRequest(). So you are executing all CPU bound code on one thread: the for loop thread. complete serialization, no parallelism at all.
When you wrap the CPU part in a task you are actually submitting the CPU part as Tasks, so they are executed in parallel.
The way you're doing, this is what happens:
|-----------HandleRequest Timeline-----------|
|CpuBoundWork Timeline| |IoBoundWork Timeline|
Try doing it like this:
private static async Task HandleRequest()
{
await IoBoundWork();
CpuBoundWork();
}
It has the advantage of starting the IO work and while it waits, the CpuBoundWork() can do the processing. You only await at the last moment you need the response.
The timeline would look somewhat like this:
|--HandleRequest Timeline--|
|Io...
|CpuBoundWork Timeline|
...BoundWork Timeline|
On a side note, open extra threads (Task.Run) with caution in an web environment, you already have a thread per request, so multiplying them will have a negative impact on scalability.
You've indicated that your method ought to be asynchronous, by having it return a Task, but you've not actually made it (entirely) asynchronous. You're implementation of the method does a bunch of expensive, long running, work synchronously, and then returns to the caller and does some other work asynchronously.
Your callers of the method, however, assume that it's actually asynchronous (in entirety) and that it doesn't do expensive work synchronously. They assume that they can call the method multiple times, have it return immediately, and then continue on, but since your implementation doesn't return immediately, and instead does a bunch of expensive work before returning, that code doesn't work properly (specifically, it's not able to start the next operation until the previous one returns, so that synchronous work isn't being done in parallel).
Note that your "fix" isn't quite idiomatic. You're using the async over sync anti-pattern. Rather than making CpuBoundWork async and having it return a Task, despite being a CPU bound operation, it should remain as is an HandleRequest should handle indicating that the CPU bound work should be done asynchronously in another thread by calling Task.Run:
private static async Task HandleRequest()
{
await Task.Run(() => CpuBoundWork());
await IoBoundWork();
}

How to async this long running method?

I have this method which I would like to run asynchronously so that I can do other things while it runs. It does not rely on any other Async method (it doesn't call out to another resource, download a file or anything). I would like to avoid using new Task(), Task.Factory.StartTask() and Task.Run(), if possible.
Is it possible to run this method asynchronously, with tidy, readable code and without using Task explicitly?
If not, what is the tidiest way of running the method asynchronously?
Note: Please don't be concerned with the silly logic in the method - I have boiled it down to be deliberately slow but not show my actual code.
public static void main(string[] args)
{
RunMySlowLogic();
}
private void RunMySlowLogic()
{
while (true)
for (int i=0; i<100000000;i++)
if (i == new Random().Next(999))
return true;
}
Currently, I believe that I would need to wrap the method in a lambda or Task and mark it async. Where would the await go?
You're confusing two different things. You can run this in the background, and this method can be asynchronous. These are 2 different things and your method can do either, or both.
If you do something asynchronous in that method, like Task.Delay or some non-blocking I/O then call that method, await the returned task and make the method itself async:
async Task RunMySlowLogicAsync()
{
while (true)
{
// ...
await Task.Delay(1000);
}
}
If you don't have such a thing then your method isn't asynchronous, it's synchronous. You can still run it in the background on a different (ThreadPool) thread while you do other things using Task.Run:
var task = Task.Run(() => RunMySlowLogic());
There are multiple ways of executing code asynchronously in the .NET environment. Have a look at the Asynchronous Programming Patterns MSDN article.
Tasks are to make your job easier. I think the only valid reason to avoid using tasks is when you are targeting an older version of .NET.
So without Tasks, you can start a thread yourself, or use a ThreadPool (Tasks do this internally).
public static void main(string[] args)
{
var are = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(RunMySlowLogicWrapped, are);
// Do some other work here
are.WaitOne();
}
// you have to match the signature of WaitCallback delegate, we can use it to communicate cross-thread
private void RunMySlowLogicWrapped(Object state) {
AutoResetEvent are = (AutoResetEvent) state;
RunMySlowLogic();
are.Set();
}
private bool RunMySlowLogic()
{
while (true)
for (int i=0; i<100000000;i++)
if (i == new Random().Next(999))
return true;
}

async ctp recursion

I'm about 15 minutes into my first play with the async CTP... (nice).
Here's a really simple server I've knocked together:
internal class Server
{
private HttpListener listener;
public Server()
{
listener = new HttpListener();
listener.Prefixes.Add("http://*:80/asynctest/");
listener.Start();
Go();
}
async void Go()
{
HttpListenerContext context = await listener.GetContextAsync();
Go();
using (var httpListenerResponse = context.Response)
using (var outputStream = httpListenerResponse.OutputStream)
using (var sw = new StreamWriter(outputStream))
{
await sw.WriteAsync("hello world");
}
}
}
As can be seen, the async method Go calls itself. In classic non-async world, this would cause a stack overflow. I assume that this isn't the case with an async method, but I'd like to be sure, one way or the other. Anyone?
Let's break it down into something simpler:
async static void Go()
{
await Something();
Go();
await SomethingElse();
}
How does the compiler deal with this?
Basically this becomes something like this sketch:
class HelperClass
{
private State state = STARTSTATE;
public void DoIt()
{
if (state == STARTSTATE) goto START;
if (state == AFTERSOMETHINGSTATE) goto AFTERSOMETHING;
if (state == AFTERSOMETHINGELSESTATE) goto AFTERSOMETHINGELSE;
START:
{
state = AFTERSOMETHINGSTATE;
var awaiter = Something().MakeAnAwaiter();
awaiter.WhenDoneDo(DoIt);
return;
}
AFTERSOMETHING:
{
Go();
state = AFTERSOMETHINGELSESTATE;
var awaiter = SomethingElse().MakeAnAwaiter();
awaiter.WhenDoneDo(DoIt);
return;
}
AFTERSOMETHINGELSE:
return;
}
static void Go()
{
var helper = new HelperClass();
helper.DoIt();
}
Now all you have to remember is that when each asynchronous operation completes, "DoIt" is scheduled to be called again by the message loop (on the appropriate instance of the helper of course).
So what happens? Work it out. You call Go for the first time. That makes helper number one and calls DoIt. That calls Something(), gets a task back, makes an awaiter for that task, tells the awaiter "when you're done, call helper1.DoIt" and returns.
A tenth of a second later the task completes and the message loop calls helper1's DoIt. helper1's state is AFTERSOMETHINGSTATE, so we take the goto and call Go. That makes helper2 and calls DoIt on that. That calls Something(), gets a task back, makes an awaiter for that task, tells the awaiter "when you're done, call DoIt on helper2" and returns control back to helper1's DoIt. That calls SomethingElse, makes an awaiter for that task, and tells it "when you're done doing something else, call helper1's DoIt". It then returns.
Now we have two tasks outstanding and no code on the stack. One of the tasks will complete first. Suppose the SomethingElse task completes first. The message loop calls helper1.DoIt(), which immediately returns. Helper1 is now garbage.
Later the message loop calls helper2.DoIt(), and branches to AFTERSOMETHING. Now Go() is called, which creates helper3...
So no, there's no unbounded recursion here. Every time Go executes it runs as far as asynchronously starting Something() and then it returns to its caller. The call to the stuff after "something" happens later. "Go" is only ever on the stack once at a time.

Categories

Resources