Asynchronous C# [duplicate] - c#

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.

Related

Why the async tasks not executed correctly? [duplicate]

This question already has answers here:
Running multiple async tasks and waiting for them all to complete
(10 answers)
Closed 2 years ago.
I have a project to submit job to AWS state machine and monitor the job status. So I implement the code like following pseudo code:
Two tasks are calling in the main function:
public static void Main(string[] args)
{
ExeJobs("1").Wait();
MonitorJobs().Wait();
}
In MonitoryJobs task, do something like:
public static async Task MonitorJobs()
{
int retry = 0;
for (int i = 0; i < retry; i++)
{
// Check History event here if find job id. else keep looping;
....
}
}
In ExeJobs task, do something like:
public static async Task ExeJobs(string jobId)
{
await SubmitJob(jobId);
ExecutionStatus status = ExecutionStatus.RUNNING;
while (status == ExecutionStatus.RUNNING)
{
status = await MonitorJobStaus(jobId);
}
}
I expected the MonitorJobs() is a thread keep live till I find the job execute status when it's running ExeJobs(). However it looks the MonitorJobs() task cannot start before ExeJobs() finish its while(status == ExecutionStatus.RUNNING) loop.
I wish MonitorJobs() can be running during the while loop in the other task and it should be expected result since they are two threads.
Anyone knows what's wrong here? Thanks
Wait will synchronously block until the task completes. So the current
thread is literally blocked waiting for the task to complete. As a
general rule, you should use "async all the way down"; that is, don't
block on async code.
public static async Task Main(string[] args)
{
await ExeJobs("1");
await MonitorJobs();
}
Wait will block until the task is finished. Also How your program will behave will be depended on what actually is happening inside your async tasks. You can use Task.WhenAll (making your main method async):
public static async Task Main(string[] args)
{
await Task.WhenAll(ExeJobs, MonitorJobs);
}
This will start both tasks (assuming that ExeJobs is actually asynchronous) and wait until both finish.
So you need to understand that when you await something, execution in that scope stops until the task is completed. If you want to have the execution keep going without waiting for it to finish, you need to assign it to a task and you can wait for it to finish after.
public static async Task Main(string[] args)
{
// start ExeJobs task but don't wait for it to finish
var jobTasks = ExeJobs("1");
// start monitor task but don't wait for it to finish
var monitorTask = MonitorJobs();
// wait for both tasks to finish before returning
await Task.WhenAll(jobTasks, monitorTask);
}

Why does this task cause a deadlock? [duplicate]

This question already has answers here:
An async/await example that causes a deadlock
(5 answers)
Closed 4 years ago.
.NET 4.7.2 website
using System;
using System.Threading.Tasks;
using System.Web;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
string input = Input.Text;
bool iWantDeadlock = input == "yes";
string key = iWantDeadlock
? GetHashFragmentAsync(input).GetResultSafely()
: Task.Run(() => GetHashFragmentAsync(input)).Result;
Response.Redirect(key);
}
}
private static async Task<string> GetHashFragmentAsync(string key)
{
await Task.Delay(100);
return "#" + HttpUtility.UrlEncode(key);
}
}
public static class TaskExtensions
{
public static T GetResultSafely<T>(this Task<T> task)
{
return Task.Run(() => task).Result;
}
}
I made a very simple page, with a textbox, that puts the input in the hashfragment of the page after submitting it.
I was reading up on Tasks and deadlocks (after I ran into some code from others that was causing one).
The solution seems to be to do this:
Task.Run(() => GetHashFragmentAsync(input)).Result;
So I thought, let's make that an extension for clarity and easy use.
public static class TaskExtensions
{
public static T GetResultSafely<T>(this Task<T> task)
{
return Task.Run(() => task).Result;
}
}
This however causes a deadlock. The code is the same, but works very different.
Can someone explain this behaviour?
Because when you use GetHashFragmentAsync(input).GetResultSafely() you have actually 2 tasks not 1.
GetHashFragmentAsync(input) returns already started task. Then you call GetResultSafely() which creates another task.
When you wait for a task on UI thread you deadlock, because task cannot go back to synchronization context thread. When you have two tasks, then the second task can wait synchronously, because parent task is not on UI thread, but on ThreadPool thread, which doesn't have synchronization context.
When you call any IO based code, you should never call Task.Run. Simply write
protected async void EventHandlerMethod(object sender, EventArgs e)
{
await GetHashFragmentAsync(input);
}
Here is what happens
GetHashFragmentAsync(input) // Start Task number 1
.GetResultSafely() // Start task number 2 from task number 1 (no synchronization context)
// .Result returns back to task 1
Second scenario
Task.Run(() => GetHashFragmentAsync(input)) // UI thread so, capture synchronization context
.Result // Wait for UI thread to finish (deadlock)
When you call GetHashFragmentAsync(input) the current synchronization context is captured by the C# async/await machinery. The method returns a started task which depends on the UI thread. You try to use Task.Run to move that task of the critical UI thread but it's too late.
GetHashFragmentAsync(input) must be called on a non-UI thread already. Wrap it in Task.Run.
Here's a helper method that works by taking a factory:
public static T GetResultSafely<T>(Func<Task<T>> task)
{
return Task.Run(() => task()).Result;
}
The factory is called on the thread pool.
I should say that normally the best solution is to use async APIs through and through, or to stay totally synchronous. Mixing is problematic for correctness and performance reasons. But it absolutely can be done safely.

Task<TResult>.Result vs await a task [duplicate]

This question already has answers here:
Await on a completed task same as task.Result?
(2 answers)
Closed 6 years ago.
I writing a small example to get value 5 in method TestMethod, I have 2 ways to do that:
static async Task<int> TestMethod()
{
await Task.Delay(0);
return 5;
}
static async Task Caller()
{
Task<int> test = TestMethod();
int i = await test;
Console.WriteLine("i: " + i);
int k = test.Result;
Console.WriteLine("k: " + k);
}
The output:
i: 5
k: 5
So, my questions are: what's the difference between await test and test.Result? And when to use await test/test.Result?
First version
static void Caller()
{
Task<int> test = TestMethod();
int k = test.Result;
Console.WriteLine("k: " + k);
}
In this version the async keyword would be obsolete. This is a synchronous method. The executing thread blocks at test.Result until the task has finished.
Second version
static async Task Caller()
{
Task<int> test = TestMethod();
int i = await test;
Console.WriteLine("i: " + i);
}
This is a (kind of) asynchronous version (it's not really asynchron, it's just a synchronous method run on a different thread). The difference to the first version is that the compiler builds a state machine for this.
So the control flow of the executing thread is returned to the caller of this method when await test is reached.
When the task has finished, the execution of this method is resumed at Console.WriteLine (or more precisely at the assignment to i).
For more information about what the compiler does you can read for example this.
The second version is useful if you have a longer running task that you need to execute from an UI. Since the control is returned to the caller while awaiting the task, the UI thread is not blocked and your application stays responsive.
Task.Result is equivalent to Task.Wait Method which blocks synchronously until the task is complete.
await on the other hand waits asynchronously till the task is completed.
If you can await is better.

In C# 5, difference between async function and non-async function? [duplicate]

This question already has answers here:
Difference between returning and awaiting a Task in an async method [duplicate]
(3 answers)
Closed 8 years ago.
Suppose I have below code:
static void Main(string[] args)
{
println("begin s");
Task<int> s = CaculateSometingAsync();
println("begin s1");
Task<int> s1 = CaculateSometingAsync1();
println(s.Result.ToString());
println(s1.Result.ToString());
}
static async Task<int> CaculateSometingAsync()
{
return await Task.Factory.StartNew<int>(() =>
{
Thread.Sleep(1000);
return 100;
});
}
static Task<int> CaculateSometingAsync1()
{
return Task.Factory.StartNew<int>(() =>
{
Thread.Sleep(1000);
return 200;
});
}
The result is as follow:
16:55:38 begin s
16:55:38 begin s1
16:55:39 100
16:55:39 200
What I know about these two functions is that they have the same behavior.
Both they create one thread-pool thread to run the task.
Both
Task<int> s = CaculateSometingAsync();
and
Task<int> s1 = CaculateSometingAsync1();
don't block the main thread.
So is there any difference between this two functions?
The difference is the way you're using it.
In the first one (CaculateSometingAsync) you're declaring it as asynchronous, and then you await inside it until it's done. You then return whatever it returns.
In your second one (CaculateSometingAsync1) you just use it as a "fire and forget" kind of things, so it goes away, waits, and returns straightto where you called it from.
(and why do you use a method println to print the string ? :) )
you await inside the CaculateSometingAsync but could await on s as the method is declared async, where as you could not await on s1 as CaculateSometingAsync1 is not declared async. The way you are using the keywords means there is no difference in bahviour

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

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");
}
}
}

Categories

Resources