-
-
Notifications
You must be signed in to change notification settings - Fork 362
C Asynchronous Programming Full Tutorial Async Await Task and Deadlock Fix by ConfigureAwait
Full tutorial link > https://www.youtube.com/watch?v=I4cnX_odC1M
In this lecture video, I am going to explain #asynchronous #programming concepts when using .NET Core 7 with C# #programming language. I will code a #WPF application to demonstrate #Async, #Await, #ConfigureAwait, and #Task concepts while doing asynchronous coding. I will show how ConfigureAwait is important to prevent deadlocks while using "async" and "await" keywords.
The code repository of this lecture :
Moreover, we cover the following #howto topics:
-
How to do asynchronous programming with C# and .NET
-
How to use Async, Await and ConfigureAwait
-
How to use Task, Task.Wait and ContinueWith
-
How to utilize Dispatcher.BeginInvoke to update UI elements from different tasks, sub-tasks, threads
-
How to utilize Thread.CurrentThread.ManagedThreadId to see which code is executed in which thread
-
How to download source of a web page / URL asynchronously and properly with using HttpClient and Content.ReadAsStringAsync
00:00:00 Introduction Task, Async, Await and composing the demo application
00:02:18 Generating Async deadlock causing example
00:08:03 How to see thread IDs during the runtime
00:11:47 How to fix deadlock
00:13:50 How to use ConfigureAwait properly
00:14:48 How to make UI responsive with proper Async Await usage
00:17:09 How to make async but main thread blocking code with TaskFactory.StartNew and Task.Wait
00:20:52 How to make fully asynchronous and non-blocking UI with TaskFactory and ContinueWith
00:23:36 How to update UI thread from sub-thread with Dispatcher
We have manually corrected the subtitles for the video so watch the tutorial with subtitles on if you have a hard time understand
Please join Our Discord server for asking questions and have discussions: https://discord.gg/rfttctFewW
Please follow us on Twitter: https://twitter.com/SECourses
Please follow us on Facebook: https://www.facebook.com/OfficialSECourses
If you are interested in programming our playlists will teach you how to program and code from scratch: https://www.youtube.com/c/SECourses/playlists
[1] Introduction to Programming Full Course with C# playlist
[2] Advanced Programming with C# Full Course Playlist
[3] Object Oriented Programming Full Course with C# playlist
[4] Asp #NETCore V5 - MVC Pattern - Bootstrap V5 - Responsive Web Programming with C# Full Course Playlist
[5] Artificial Intelligence (AI) and Machine Learning (ML) Full Course with C# Examples playlist
[6] Software Engineering Full Course playlist
[7] Security of Information Systems Full Course playlist
Thumbnail: Freepik (@fullvector) - Data processing, software program development, code review, database concept. #dotnet #dotnet7 #csharp
-
00:00:00 Hello everyone. I am Dr. Furkan Gözükara. In this lecture video, I am going to explain asynchronous
-
00:00:07 programming concepts when using .NET Core 7 with C-Sharp programming language. I will code a WPF
-
00:00:14 application to demonstrate async, await, configure await and task concepts while doing asynchronous
-
00:00:21 coding. I will show how ConfigureAwait is important to prevent deadlocks while using
-
00:00:27 async and await keywords. Let's start coding with composing a .NET Core 7 WPF application.
-
00:00:33 If your Visual Studio is lacking .NET Core 7, just download latest Visual Studio Community
-
00:00:39 Edition and update it to the latest version. Here let me show you how to update your Visual Studio.
-
00:01:01 As you can see, my Visual Studio is up to date. Its version is 17.4.1. Okay,
-
00:01:08 so let's start composing our WPF project. I am going to pick WPF application. You
-
00:01:15 can also look for it with searching WPF. And then you see there is ASP.NET Core WPF app.
-
00:01:24 Then click next. Okay, it will be in my desktop. Let's say
-
00:01:32 async programming. I am going to pick .NET 7 and this is .NET Core web app. Let's fix
-
00:01:41 it quickly. Okay, here WPF application and it is with .NET Core. Okay, next.
-
00:01:53 You see it says that there is WPF application. Okay .NET Core 7.
-
00:02:06 Okay, application is started now. The interface is loaded. So let's start
-
00:02:14 with generating a button control. First I will show you how a deadlock can happen when we are
-
00:02:23 doing asynchronous programming with async and await keywords. Let's say test async deadlock.
-
00:02:42 Okay and with double clicking it I am going to compose click event here.
-
00:02:49 Okay, so let's assume that we have an async method that will return a string.
-
00:02:57 Let's say return source code of a web page as a string. Okay.
-
00:03:18 I will use HTTP client.
-
00:03:24 Okay and inside here we will use.
-
00:03:34 We will use HTTP response.
-
00:03:40 Okay. Sorry not not necessarily we need that.
-
00:03:56 You see it has suggested me to auto complete is like this and it's correct. And we will return.
-
00:04:09 Response request. Content. Okay, then let's see. Okay, like this.
-
00:04:24 All right. However, since this is asynchronous with async keyword. We need to say await here.
-
00:04:34 And since this is an async method, we can't just return it like this. We have to return a task
-
00:04:43 like this. Okay. And let's add a label or a text
-
00:04:49 block to display source code. I'm going to pick a text block.
-
00:04:57 Okay, let's name it as block source code.
-
00:05:05 Okay, I have named it as txt block source code.
-
00:05:10 Then let's assign text of txt block source code equal to return source code of
-
00:05:21 my developed web game web based game, which is HTTPS www monsters MMORPG.com. Okay.
-
00:05:33 However, to access result of async method, we have to get result. So what does this async do?
-
00:05:45 Async means that that method is asynchronous and it will not block the thread that it is executed.
-
00:05:58 However, to get its result, I need to use await keyword.
-
00:06:04 And when you use await keyword, then you don't need to access it by result.
-
00:06:12 So when I run this code, what will happen? Let's see. Let's run and run our application and see.
-
00:06:26 Okay, I am clicking it and you see it has returned the result as expected. Because because there is a
-
00:06:39 key issue here, you see my button click is now also asynchronous. However, if I don't want to
-
00:06:48 make it asynchronous, then I need to return async keyword here that the Visual Studio
-
00:06:54 did put automatically and I need to use result like this. Okay, let's see now what happens.
-
00:07:06 Okay, I'm clicking and my application is completely frozen. Do you know why?
-
00:07:13 Because currently the UI thread is blocked. The reason is that UI
-
00:07:20 thread is waiting to waiting the result of this method call and this method call
-
00:07:28 is not able to execute because the UI thread is already frozen. So how can I solve this problem?
-
00:07:40 So for solving this problem, I can use configure await. So when you set configure await false
-
00:07:49 on an async method, this means that this method can now run on a different thread.
-
00:07:59 Okay, so to see the thread IDs that each method is running, let's use managed thread ID code.
-
00:08:11 Okay, let's write it to our output window with thread.
-
00:08:23 Okay, current thread manage thread ID. Okay, so it says that thread is
-
00:08:27 not existing in the current context for that I am adding using threads.
-
00:08:34 Okay, so this will print the thread ID of the thread that this line is executed. Then let's
-
00:08:42 also see the thread ID here. Let's also add some extra information as the inside
-
00:08:54 here. Then let's also write it as like this inside here. And then one second.
-
00:09:08 Okay, inside the first using statement inside using HTTP client and inside here. Okay, so
-
00:09:28 first, let's run it without configure, await and see which output we are getting.
-
00:09:40 Okay, let's check out the output window. So, okay, we see that inside btnTestAsyncDeadLock_Click,
-
00:09:51 which is here, the thread ID is one. It is expected because we are currently inside
-
00:09:58 the main UI thread, and it is one and in the source code. So it has entered here, we are
-
00:10:06 still inside thread ID one. And then we have entered here as well inside using HTTP client.
-
00:10:16 However, since we are doing await here, now it becomes asynchronous call and it
-
00:10:27 locks our execution. And you see we didn't enter inside here because the UI thread is
-
00:10:37 now awaiting that response. So the main thread is UI thread is locked, frozen.
-
00:10:46 And this execution is waiting that thread to be released. Okay, so when I add this execution,
-
00:11:00 configure await as false. Now let's see how to output. Let's see the output again.
-
00:11:11 Okay, the button is still frozen because it is not anymore asynchronous. However, now we can
-
00:11:17 see inside using response. You see inside here now running in a different thread and the thread ID is
-
00:11:24 six. Okay, so this is where configure await is very useful because when you set ConfigureAwait
-
00:11:36 false, then that asynchronous method call becomes, starts running in a different thread. Okay,
-
00:11:48 so if we don't want the interface to be frozen, let's copy and paste this button.
-
00:11:54 And let's say btn test proper async code. Okay, proper async code.
-
00:12:05 Okay, so this will cause a deadlock, so I'm going to delete this.
-
00:12:13 All right. Oh, we don't need that actually. So this is return source code with
-
00:12:23 or let's say let's add an option here. Bool cause deadlock equal to false. Okay.
-
00:12:37 Okay, so if you don't want to cause deadlock, then configure await. Then I need to
-
00:12:46 give opposite of this. So by default it will cause a deadlock and to cause a deadlock. We need
-
00:12:54 to give configure await true. Okay. Maybe this make make you confused. So let's say bl configure
-
00:13:06 await by default. Let's make it false so it won't cause a deadlock.
-
00:13:13 Okay, now it won't cause a deadlock. So to cause a deadlock, I need to provide it true. Okay. Yes,
-
00:13:25 now it will cause a deadlock. Let's try. Okay, so you see we are never getting inside here.
-
00:13:36 So now it is deadlocked because main thread the UI thread is awaiting the result and the result
-
00:13:45 is awaiting main thread UI thread to be released to run. Okay, so each one is awaiting each one
-
00:13:54 and it causes a deadlock. All right, so let's make this as none that's locking or let's say
-
00:14:07 configure await asynchronous code. Okay, I need to change its click event. We can
-
00:14:18 configure await async code. Okay. This time we are just going to run it with false and let's try.
-
00:14:36 Okay, still, the interface is frozen during the runtime because this button click is not
-
00:14:42 asynchronous. However, it is not that locked. Okay. And let's also add another button, which
-
00:14:52 will be responsive. We can responsive. Okay, async click. Let's say it as responsive async click.
-
00:15:08 Okay, and I need to generate a new click event. Okay, so I'm going to mark this method as async
-
00:15:20 and I can also let Visual Studio to mark it as async automatically with await.
-
00:15:30 Okay, now you see it is automatically marked as async. Okay,
-
00:15:38 now in this case, it will not freeze the interface. Let's try. Okay, let's try again.
-
00:15:49 Okay, the interface is not freezing. However, meanwhile, the text block is getting updated.
-
00:15:56 During that time, the interface will freeze, of course, because it is getting updated.
-
00:16:02 And since source code is pretty big, it is not displayed entirely here.
-
00:16:09 It takes some time. Actually, maybe we can fix it with. Okay. I don't know. Let's see.
-
00:16:19 Max with max height, for example, let's say 6000 and let's see what happens.
-
00:16:28 Okay, probably we need to add scroll bars. Let's see horizontal alignment. No scroll,
-
00:16:37 scroll bar. Okay, scroll. No. Okay, anyway, it is not important for this lecture. And there is one
-
00:16:48 another methodology, one more method, actually two more methodology. So let's also see them.
-
00:16:54 I'm going to expand this a little bit more. Why? Okay,
-
00:17:07 here. Okay. Now I will use task methodology. Okay, so btnTaskExample.
-
00:17:17 I will call this as task version one. Okay, and let's generate this click event. So this time I
-
00:17:28 will start this code inside or let's say as a task task. Let's say var task = Task.Factory.StartNew.
-
00:17:42 Okay. It automatically completes. Very nice. And let's call it like this.
-
00:17:50 And by the way, still this is a async method. So I need to call await.
-
00:17:59 And I need to assign this into a string variable. Let's say string source.
-
00:18:10 Like this. And let's say the source is equal to await.result. Okay. Okay.
-
00:18:24 I need to provide the source code, of course. I mean the URL. All right. And no result. Okay.
-
00:18:34 And then what do I need to do is. I can do task.wait. This will make it synchronous.
-
00:18:45 And then I can assign the source like this. Okay. It says that this can be null here. So
-
00:18:57 let's initialize it like this. All right. You see, it is still pretty responsive.
-
00:19:08 But we never get the result. So in this case. We need to set configure await true.
-
00:19:20 Otherwise it will return from that asynchronous and the task wait will never work. I suppose.
-
00:19:28 Let's try. Yes, we did enter inside the request. Okay. All right. This is the sound of my girl.
-
00:19:42 Okay, we do. We do enter inside the request. However, it is obvious that the source code
-
00:19:52 is immediately executed without waiting. So the task is completed immediately. Since we
-
00:20:00 are doing an asynchronous call here. And therefore, maybe we need to do. Let's see.
-
00:20:11 Okay, we need to turn this asynchronous call into a synchronous call because we are already spawning
-
00:20:18 a new task. And here we just need to provide or let's say, get result. Okay. And we need to
-
00:20:28 remove the wait keyword. All right. Now, since this will run inside a different thread than the
-
00:20:37 main thread, then it won't cause any problem as a deadlock. However, our interface will be still
-
00:20:46 frozen. Let's try. Okay. It is working. Now let's make another example of task with ContinueWith. So
-
00:20:58 I will call this task as version two. Okay. And let's say btn task version two. All right.
-
00:21:11 Okay. Okay. So in this case, we are going to use a different methodology as
-
00:21:23 continue with. All right. And it says we need a new action. Okay. Action. Okay. And. It says task.
-
00:21:43 Okay, one moment. It is pretty simple, actually. So we are going to call this T1 parameter,
-
00:21:53 which will be when we hover it, we see that it is task T1. So this means that it is the result
-
00:21:59 of execution of this task. Okay. And inside that we will have the result of the task. Therefore,
-
00:22:10 I will assign. I don't need this anymore. The text as equal to Ok.
-
00:22:21 T1. Okay. Result. Okay. And I just need to return the result of the inner execution. Okay.
-
00:22:35 Now this is supposed to not block anything and update the text block. Let's try. Okay.
-
00:22:41 It is not block it. Okay. Inside is called. All right. So we have a little bit. Another problem.
-
00:22:51 Okay. Which is this is task return. Okay. We are waiting it. We are locking it.
-
00:22:59 So let's try. Maybe we didn't wait. Okay. We did enter inside. Oh, we have a system invalid
-
00:23:08 operation exception somewhere. Okay. Let's put a break point here. Maybe our error is there.
-
00:23:17 Okay. And. When we debug the result. Okay. The result is there as well. Oh, I know the reason.
-
00:23:26 I know the problem. The problem is we cannot update the UI element inside another task. So
-
00:23:37 I need to do use dispatcher. Let's say begin invoke new action.
-
00:23:45 And inside that I need to assign it. Okay. So you see it defines a new action like this. And it's
-
00:23:54 anonymous call because we don't get we don't need any parameter. Actually, it is like here,
-
00:24:00 as you can see. But this is empty action. And yes, now it should work. Let's try.
-
00:24:10 OK. All right. I have shown multiple ways to use async and task to do asynchronous programming.
-
00:24:22 I hope you have enjoyed. Please ask your questions in the comments section. Hopefully see you
-
00:24:30 in another video. Let me know through comment section that what questions do you have? What
-
00:24:39 topics do you wonder? What would you like to see in my next video? OK. Hopefully see you later.
