Run async function on background thread? - c#

I'm working on a project that includes a server and a client.
The client sends every second a UDP packet to the server, and according to the server's response it might open a TCP connection with the server (and recieve files from the server), the client's program has a GUI which I don't want to block (made in WPF MVVM), and also it's problematic to start async function on constructor of the MainWindow as constructors can't be async.
So my question is, can I and should I run async functions on a background thread? Does the async improve performance if it's on a background thread, I'm talking about the difference between these options:
public MainWindow()
{
InitializeComponent();
DirectoryViewModel DirectoryVM = new DirectoryViewModel();
this.DataContext = DirectoryVM;
DirectoryVM.StartListen(); //Unwanted as constructor won't finish
}
To
public MainWindow()
{
InitializeComponent();
DirectoryViewModel DirectoryVM = new DirectoryViewModel();
this.DataContext = DirectoryVM;
Task.Run(DirectoryVM.StartListen()); //Possible but async might be faster
}
To
public MainWindow()
{
InitializeComponent();
DirectoryViewModel DirectoryVM = new DirectoryViewModel();
this.DataContext = DirectoryVM;
Task.Run(async () => await DirectoryVM.StartListenAsync()); //Is it faster than the second option?
}
From what I've seen I shouldn't run async code on background thread like this, but why? Isn't it faster than running sync code on a background thread?
Also I guess it's not really different but on my server I'll create a constant running thread that listens for tcp connections and will send files over it, should I make the send file function async or not?
Thanks!

... is it ok to start async method on a seperate thread ...
I think you fundamentally misunderstand the async methods. Calling an async method does not create a new thread or offload the entire method onto any other thread. Calling an async method is like calling any other method, but it maybe at some point returns execution back to the caller (with a Task as a promise) and finishes its remaining job at some point.
Though it is possible to spin up an always running periodic listener using async method, it is rather against its purpose.
When you call an async method, you expect it will be run to completion within a reasonable time (hence why you want to await on it), but it might takes long enough time to do something else meanwhile. In your case, you should explicitly start a new background task or thread what does the periodic check for you. It can be a new thread or better, a new task (Task.Run for example).
From what I've seen I shouldn't run async code on background thread
like this, but why?
According to your comments the DirectoryVM.StartListen() starts the constantly running listening, what does not have to be async. Unless it does any async calls, it is not something awaitable.
Isn't it faster than running sync code on a background thread?
Async is not about speed, but about thread blocking. It does not matter if the thread is foreground or background, using async method for an I/O operation, like calling an http endpoint or sending a UDP packet is always beneficial, if the thread can do other things while waiting, or otherwise blocking that thread might cause other issues.
Also I guess it's not really different but on my server I'll create a
constant running thread that listens for tcp connections and will send
files over it, should I make the send file function async or not?
You should, if it is beneficial. See previous part.

From what I've seen I shouldn't run async code on background thread like this, but why?
I'm not aware of any recommendations not to run asynchronous code with Task.Run.
Task.Run should be avoided on ASP.NET (for both synchronous and asynchronous code), but that doesn't apply here since you have a GUI app.
Isn't it faster than running sync code on a background thread?
No. The code will not be any faster. async is about freeing up threads, not running faster.
I think the concern that you've seen is that of ignoring tasks. Using Task.Run and ignoring the task it returns is problematic because that's a form of fire-and-forget. So if your loop fails due to an exception, your application would never know. One way around this is to await the task from an async void method. For example, as your Window's Initialized event handler:
async void Window_Initialized(object, EventArgs)
{
await Task.Run(DirectoryVM.StartListen);
// or, if asynchronous:
await DirectoryVM.StartListenAsync();
}

Related

Does async (one task) make sense in MVC?

I am using async/await in MVC, but only when I have more than one task (WaitAll).
I understand that having only one task is good to have the UI free, in case of WPF or Windows Form, but does it make sense for MVC to have only one task and await for that?
I've seen it a lot in code, in MVC, but I don't get the advantages.
HTTP requests are handled by thread pool threads.
If you block a thread, it will not be able to do other work. Because the total number of threads is limited, this can led to the starvation of the thread pool and new requests will be denied - 503.
Using async code, the thread is released back to the thread pool, becoming available to handle new requests or the continuations of async code.
Like on client UIs, on the server, async code is all about responsiveness, not performance. Requests will take longer but your server will be able to handle more requests.
It depends on what you are trying to achieve. For instance, if you have multiple calls to multiple services you can always do it in a way that only the last call makes the rest of the system "wait".
You can optimise your code in a way that X asynchronously calls to services start (almost) at the same time without having to 'await' for one another.
public async Task RunSomethings()
{
var something1 = AsyncCall1();
var something2 = AsyncCall2();
var something3 = await AsyncCall3();
}
private async Task<Something1> AsyncCall1()
{
return await Something1();
}
private async Task<Something2> AsyncCall2()
{
return await Something2();
}
private async Task<Something3> AsyncCall3()
{
return await Something3();
}
I hope it helps.
Good question. Using asynchronous methods is all about using the resources effectively as well as give a good user experience. Any time you need to call on a resource that could take time to collect, it's good to use an async call.
This will do a few things. First, while a worker thread is waiting for data, it can be put on 'hold' so to speak, and that worker thread can do something else until the data is returned, an error is returned or the call just times out.
This will give you the second advantage. The interface the user is using to call the resource will be released, temporarily, to do other things. And overall, less server resources are consumed by idle processes.
I'd recommend watching the videos on this page here: https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async
It's probably the clearest explanation that can help leapfrog your learning on async.

What makes these async method calls different?

I was reading a chapter about the await and async keywords in my C# book.
It was mainly explaining these kinds of method calls, where the caller uses the await keyword to wait for the called method to finish.
In this simple example I see no advantage but more importantly no difference in these 3 calls. Can anyone explain what difference it makes to the flow of the application? Is it only useful when the calling thread is the main GUI thread?
static async Task Main(string[] args)
{
WriteText();
await WriteTextAsync();
WriteTextAsync().Wait();
}
static void WriteText()
{
Thread.Sleep(3_000);
Console.WriteLine("Hello");
}
static async Task WriteTextAsync()
{
await Task.Run(() =>
{
Thread.Sleep(3_000);
Console.WriteLine("Hello");
});
}
Ps: If the calling thread of the method is waiting for the method to finish anyway it might as well be a normal call?
As my understanding about your question is
If the program waits for the response in await WriteTextAsync() line then what will be the benifit?
For client applications, such as Windows Store, Windows desktop and Windows Phone apps, the primary benefit of async is responsiveness. These types of apps use async chiefly to keep the UI responsive. For server applications, the primary benefit of async is scalability.
I will try to explain from the web-app point of view.
Suppose you have a web application depends on external resources like database call, when a client initiates a request ASP.NET takes one of its thread pool threads and assigns it to that request. Because it’s written synchronously, the request handler will call that external resource synchronously. This blocks the request thread until the call to the external resource returns. Figure 1 illustrates a thread pool with two threads, one of which is blocked waiting for an external resource.
Figure 1 Waiting Synchronously for an External Resource
Now if third client requests at the same time then there is no thread in thread pool available to assign the third request.
In asynchronous call, thread will not be stuck rather will be released and comes back to the thread pool which will facilitates to serve the third call.
When request server activities ends linke database call ends then SynchronizationContext resumes that call and returns repose to client.
Bellow image in simple analogy of aync call
There is lot of things happens under the hood. I wrote this maily from Async Programming : Introduction to Async/Await on ASP.NET and my understanding. It is highly recommended to have clear understanding before using async-wait.
I'll be referring to:
//Call 1
WriteText();
//Call 2
await WriteTextAsync();
//Call 3
WriteTextAsync().Wait();
The first call doesn't have any problem, if what you want to do is a synchronous wait. In a Console application, this is quite normal.
The problem arises in programs with a UI or those that require the best use of CPU resources, the most common case being web applications.
Call 2, using await performs an asynchronous wait for the result of WriteTextAsync. In its own, that's fine and what's considered normal. However, WriteTextAsync is a very good example of something you should never do:
static async Task WriteTextAsync()
{
// Let's create a Thread
await Task.Run(() =>
{
// just to block it completely, having it do nothing useful
Thread.Sleep(3_000);
Console.WriteLine("Hello");
});
}
Rather, the author should have used:
static async Task WriteTextAsync()
{
// Let's *not* create a new thread
await Task.Delay(3_000);
Console.WriteLine("Hello");
}
Maybe they were to point this out further down the line, but you didn't give us the book name to know this.
Call number 3 is what you would have to do when the calling method cannot be an async one and you have to call an async method, so:
// Think that for some reason you cannot change the signature,
// like in the case of an interface, and an async void would make your code
// never complete correctly
static void Main(string[] args)
{
//Call 3
WriteTextAsync().Wait();
}
Overall, I would suggest you to find a better book. Examples are easier to understand when asynchronous code is actually required.
When you say WriteText(), WriteText() will block your current thread until it completes, as it is synchronous.
When you say await WriteTextAsync(), you will spawn a new thread and you will not block computations that do not depend on the result of WriteTextAsync().
EDIT: According to Microsoft Docs When you say await WriteTextAsync(), the compiler schedules the rest of Main() for execution after WriteTextAsync() completes. Then the control is supposed to be returned to the caller of the async method. But who is the caller of Main()? As it turns out, there is no async Main() - it is actually the same synchronous Main() - and it's just syntactical sugar for not writing .Wait() inside it. So in this case this call is equivalent to WriteTextAsync().Wait()!
Finally, when you say WriteTextAsync().Wait(), you block your current thread again and wait for the result of WriteTextAsync().

Is Async/Await using Task.Run starting a new thread asynchronously?

I have read a lot of articles and still cant get understand this part.
Consider this code :
private async void button1_Click(object sender, EventArgs e)
{
await Dosomething();
}
private async Task<string> Dosomething()
{
await Task.Run((() => "Do Work"));
return "I am done";
}
First question:
When I click the button, it will Call DoSomething and await a Task that creates a Thread from the threadpool by calling Task.Run ( if I am not mistaken ) and all of this runs asynchronously. So I achieved creating a thread that does my work but doing it asynchronously? But consider that I don't need any result back, i just want the work to be done without getting any result back, is there really a need to use async/await , and if so, how?
Second question:
When running a thread asynchronously, how does that work? Is it running on the main UI but on a separate thread or is it running on a separate thread and separate is asynchronously inside that method?
The purpose of creating Async methods is so you can Await them later. Kind of like "I'm going to put this water on to boil, finish prepping the rest of my soup ingredients, and then come back to the pot and wait for the water to finish boiling so I can make dinner." You start the water boiling, which it does asynchronously while you do other things, but eventually you have to stop and wait for it. If what you want is to "fire-and-forget" then Async and Await are not necessary.
Simplest way to do a fire and forget method in C#?
Starting a new task queues that task for execution on a threadpool thread. Threads execute in the context of the process (eg. the executable that runs your application). If this is a web application running under IIS, then that thread is created in the context of the IIS worker process. That thread executes separately from the main execution thread, so it goes off and does its thing regardless of what your main execution thread is doing, and at the same time, your main execution thread moves on with its own work.
1
There's a big difference if you don't await the Task or you await it:
Case you don't await it: DoSomething is called but next sentence is executed while DoSomething Task hasn't been completed.
Case you await it: DoSomething is called and next sentence is executed once DoSomething Task has been completed.
So, the need of async/await will depend on how you want to call DoSomething: if you don't await it is like calling it the fire & forget way.
2
Is it running on the main UI but on a separate thread or is it running
on a seperate thread and separate is asynchronously inside that
method?
Asynchronous code sometimes means other thread (see this Q&A Asynchronous vs Multithreading - Is there a difference?). That is, either if the code is being executed in a separate thread from the UI one or it lets continue the processing of the UI thread while it gets resumed, it's nice because UI loop can still update the screen while other tasks are being done in parallel without freezing the UI.
An asynchronous method (i.e. async method) is a syntactic sugar to tell the compiler that await statements should be treated as a state machine. The C# compiler turns your async/await code into a state machine where code awaiting a Task result is executed after the code that's being awaited.
Interesting Q&As
You might want to review these other Q&As:
Async/Await vs Threads
What's the difference between Task.Start/Wait and Async/Await?
async/await - when to return a Task vs void?
Is Async await keyword equivalent to a ContinueWith lambda?
OP said...
[...] But does this mean that "async/await" will fire off a thread and
Task.Run also fires off a thread or are they both the same thread?
Using async-await doesn't mean "I create a thread". It's just a syntactic sugar to implement continuations in an elegant way. A Task may or may not be a thread. For example, Task.FromResult(true) creates a fake task to be able to implement an async method without requirement it to create a thread:
public Task<bool> SomeAsync()
{
// This way, this method either decides if its code is asynchronous or
// synchronous, but the caller can await it anyway!
return Task.FromResult(true);
}
The type Task<TResult> requires you to return a TResult from your task. If you don't have anything to return, you can use Task instead (which, incidentally, is the base class of Task<TResult>).
But keep in mind that a task is not a thread. A task is a job to be done, while a thread is a worker. As your program runs, jobs and workers become available and unavailable. Behind the scenes, the library will assign your jobs to available workers and, because creating new workers is a costly operation, it will typically prefer to reuse the existing ones, through a thread pool.

C# Thread.Sleep()

I need somehow to bypass Thread.Sleep() method and don't get my UI Thread blocked, but I don't have to delete the method.
I need to solve the problem without deleting the Sleep method. The Sleep method simulates a delay(unresponsive application). I need to handle that.
An application is considered non-responsive when it doesn't pump its message queue. The message queue in Winforms is pumped on the GUI thread. Therefore, to make your application "responsive", you need to make sure the GUI thread has opportunities to pump the message queue - in other words, it must not run your code.
You mentioned that the Thread.Sleep simulates a "delay" in some operation you're making. However, you need to consider two main causes of such "delays":
An I/O request waiting for completion (reading a file, querying a database, sending an HTTP request...)
CPU work
The two have different solutions. If you're dealing with I/O, the best way would usually be to switch over to using asynchronous I/O. This is a breeze with await:
var response = await new HttpClient().GetAsync("http://www.google.com/");
This ensures that your GUI thread can do its job while your request is pending, and your code will restore back on the UI thread after the response gets back.
The second one is mainly solved with multi-threading. You should be extra careful when using multi-threading, because it adds in many complexities you don't get in a single-threaded model. The simplest way of treating multi-threading properly is by ensuring that you're not accessing any shared state - that's where synchronization becomes necessary. Again, with await, this is a breeze:
var someData = "Very important data";
var result = await Task.Run(() => RunComplexComputation(someData));
Again, the computation will run outside of your UI thread, but as soon as its completed and the GUI thread is idle again, your code execution will resume back on the UI thread, with the proper result.
something like that maybe ?
public async void Sleep(int milliseconds)
{
// your code
await Task.Delay(milliseconds); // non-blocking sleep
// your code
}
And if, for reasons that escape me, you HAVE to use Thread.Sleep, you can handle it like that :
public async void YourMethod()
{
// your code
await Task.Run(() => Thread.Sleep(1000)); // non-blocking sleep using Thread.Sleep
// your code
}
Use MultiThreading.
Use a different thread for sleep rather than the main GUI thread. This way it will not interfere with your Main application

UdpClient.BeginReceive vs. UdpClient.Receive on a separate thread

There is a similar question When should I use UdpClient.BeginReceive? When should I use UdpClient.Receive on a background thread?
On that post Marc Gravell wrote
"Another advantage of the async approach is that you can always get the data you need, queue another async fetch, and then process the new data on the existing async thread, giving some more options for parallelism (one reading, one processing)."
Would you be able to give me an example of what you mean with this?
My problem is that I am listening to UDP packets but I don't have time to process them in the receiving thread as I want to return to my Receive as soon as possible as to not lose any packets in the meanwhile (being that the socket will drop any packets I don't receive, being that it isn't TCP) what would be the best way to do this?
With asynchronous IO, you can return to your caller as soon as you start the IO process. Because the nature of IO bound work is done asynchronously via the operating system, we can take advantage of this.
When you use blocking api such as UdpClient.Recieve on a different thread in order to keep your application responsive that thread will mostly block waiting for the UdpClient to complete its recieve method. With async IO, as mark said, you can free the thread until the IO operation completes and do different work in the meanwhile.
For example, we can use UdpClient.RecieveAsync, which returns a Task<UdpRecieveResult>. Because a task is awaitable (see this for more on awaitables), we can take advantage of async io:
public async Task RecieveAndDoWorkAsync()
{
var udpClient = new UdpClient(); // Initialize client
var recieveTask = udpclient.RecieveAsync();
// Do some more work
// Wait for the operation to complete, meanwhile returning control to tge calling method (without creating any new threads)
await recieveTask
}

Categories

Resources