Repository navigation
C Programming Intermediate Lecture 10 Entity Framework Search Multithreading Synchronization
Full tutorial link > https://www.youtube.com/watch?v=OQYZL5jH7gs
C# Programming (Advanced/Intermediate) Lectures (10/14) will teach you #CSharp #programming from beginner to intermediate/expert level. This course is an excellent source to learn advanced concepts in C# #coding. If you are a beginner to C#, watch our previous course lectures. The playlist link of the previous course is below.
Full playlist of the previous course: C# For Beginners
https://www.youtube.com/playlist?list=PL_pbwdIyffskoSXySh0MdiayPJsBZ7m2o
Discord ➡️ https://bit.ly/SECoursesDiscord
Patreon ➡️ https://www.patreon.com/SECourses
Technology Playlist (30+ Tutorial / Guide / News / Review Videos)
https://www.youtube.com/playlist?list=PL_pbwdIyffsnkay6X91BWb9rrfLATUMr3
Stable Diffusion Playlist (30+ Tutorial / Guide Videos)
https://www.youtube.com/playlist?list=PL_pbwdIyffsmclLl0O144nQRnezKlNdx3
Please join discord, mention me and ask me any questions. Thank you for like, subscribe, share and Patreon support. I am open to private consulting with Patreon subscription.
Full playlist of this course
https://www.youtube.com/playlist?list=PL_pbwdIyffslHaBdS3RUW26RKzSjkl8m4
You can watch for free our C# Programming, ASP .NET Core MVC programming, Machine Learning and Software Engineering related courses on our playlists page
https://www.youtube.com/@SECourses/playlists
GitHub code repository of this course (source codes of the lectures)
https://github.com/FurkanGozukara/Introduction-to-Programming-2-2021
In lecture 10:
-
Decimal values get rounded if precision is not enough
-
How to add searching / filtering feature to your entity framework context queries
-
How to capture key press events application wide and do actions based on selected tab
-
What is yield return and how to use yield return
-
Yield return example
-
What is data racing when working with multi-tasking
-
How to prevent data racing with Synchronization between threads by using lock methodology
-
How to achieve thread-safety when working with multiple threads/tasks
-
How can we use Interlocked to ensure our operations on int32 or int64 variables are thread-safe
Decimal values get rounded if precision is not enough:
In computing, decimal values represent fractional numbers with a fixed number of digits after the decimal point. These digits are commonly referred to as the precision of the number. When performing calculations with decimal values, it is important to maintain the desired level of precision to avoid inaccuracies or rounding errors.
If the precision of the decimal value is not enough, it can lead to rounding errors, which can affect the accuracy of the final result. For example, if you have a decimal value of 3.14159265359 and you want to round it to two decimal places, the result would be 3.14. However, if the precision is not enough, the result could be rounded to 3.15 instead, resulting in an inaccurate value.
To avoid rounding errors, it is important to ensure that the precision of the decimal value is sufficient for the calculations being performed. This can be achieved by using a larger number of decimal places, or by using more precise data types such as decimal instead of float or double.
How to add searching / filtering feature to your entity framework context queries:
Entity Framework is a popular Object-Relational Mapping (ORM) framework used to access and manipulate data stored in a database. One of the common requirements of an application is to search and filter data based on specific criteria. Entity Framework provides a number of methods to achieve this functionality.
The most common method is to use the Where clause to filter data based on a specific condition. For example, to filter a list of customers based on their name, you can use the following code:
You can also use other methods such as Contains, StartsWith, and EndsWith to perform more advanced searches. For example, to search for customers whose name starts with "J", you can use the following code:
Another useful method is the OrderBy clause, which allows you to sort the data based on a specific column. For example, to sort the customers by their name in ascending order, you can use the following code:
How to capture key press events application wide and do actions based on selected tab:
Capturing key press events is a common requirement in many applications, especially those with a lot of user interaction. In order to capture key press events application wide, you can use the Application class in C#.
The Application class provides an event called KeyDown, which is raised when a key is pressed down. To capture this event, you can add a handler to the KeyDown event in the Application class. For example, to capture the "A" key press event, you can use the following code:
To do actions based on the selected tab, you can use the TabControl class in C#. The TabControl class provides an event called SelectedIndexChanged, which is raised when the selected tab is changed.
-
00:00:01 Hello, dear students,
-
00:00:03 students, welcome to the 10th
-
00:00:03 welcome to the 10th lecture of the course "Introduction
-
00:00:05 lecture of the course "Introduction to Programming 2 in
-
00:00:06 to Programming 2 in C#", which is also
-
00:00:07 C#", which is also known as "
-
00:00:08 known as " Advanced
-
00:00:08 Advanced Programming". So,
-
00:00:10 Programming". So, we will continue from where we
-
00:00:11 we will continue from where we
-
00:00:13 left off in the last lecture.
-
00:00:14 last lecture.
-
00:00:18 Let's start, as always, by cloning our
-
00:00:19 cloning our code. Okay, if
-
00:00:42 code. Okay, if you remember, we had a
-
00:00:44 you remember, we had a problem with a certain
-
00:00:45 problem with a certain drug, and I
-
00:00:46 drug, and I hope you
-
00:00:47 hope you found it. Meanwhile, uh,
-
00:00:52 found it. Meanwhile, uh,
-
00:00:56 watching our video from last
-
00:00:57 video from last lecture. So I'll start by
-
00:01:01 lecture. So I'll start by showing you
-
00:01:03 showing you where the
-
00:01:04 where the error is, and then we'll
-
00:01:05 error is, and then we'll add
-
00:01:06 add search functionality to our
-
00:01:07 search functionality to our app. Good. So
-
00:01:16 app. Good. So we had a
-
00:01:17 we had a problem with a particular
-
00:01:18 problem with a particular drug and it was uh
-
00:01:22 drug and it was uh digoxin 0.25 mg and
-
00:01:29 digoxin 0.25 mg and why do you think we had a
-
00:01:31 why do you think we had a problem with
-
00:01:32 problem with that drug?
-
00:01:38 that drug? Okay, I
-
00:01:39 Okay, I used uh
-
00:01:40 used uh debugger to uh
-
00:01:43 debugger to uh
-
00:01:46 fix this error. But I think there is
-
00:01:47 error. But I think there is another way. I
-
00:01:49 another way. I already know what the
-
00:01:50 already know what the mistake was because I
-
00:01:52 mistake was because I figured it out quickly. But uh I'll
-
00:01:55 figured it out quickly. But uh I'll also try to
-
00:01:56 also try to explain it to you uh in another
-
00:01:58 explain it to you uh in another way. So, every
-
00:02:04 way. So, every query is executed in
-
00:02:05 query is executed in our database.
-
00:02:06 our database.
-
00:02:09 every query and we can intercept them
-
00:02:10 can intercept them using SQL Server
-
00:02:12 using SQL Server Profiler. Since there are no problems in
-
00:02:17 Profiler. Since there are no problems in our source
-
00:02:18 our source code,
-
00:02:19 code, the error must be
-
00:02:20 the error must be related to the
-
00:02:21 related to the database side. So
-
00:02:26 database side. So let's try to
-
00:02:27 let's try to catch this
-
00:02:28 catch this error and see
-
00:02:29 error and see what it is. Okay, I'm
-
00:02:32 what it is. Okay, I'm checking if
-
00:02:34 checking if standard SQL works. Good.
-
00:02:39 standard SQL works. Good.
-
00:02:39 standard SQL works. Good. And let's run
-
00:02:40 And let's run our
-
00:02:41 our software to
-
00:02:47 software to see which query
-
00:02:49 see which query uh is causing the error.
-
00:02:50 uh is causing the error.
-
00:02:58 Good. Good. The
-
00:02:59 The software is still
-
00:02:59 software is still loading.
-
00:03:00 loading.
-
00:03:03 Good. First we need to log in
-
00:03:04 need to log in and let's
-
00:03:07 and let's check our
-
00:03:08 check our users table
-
00:03:10 users table . Okay, let's
-
00:03:26 . Okay, let's enter as a doctor.
-
00:03:27 enter as a doctor.
-
00:03:32 Good. And I'll click " load data to
-
00:03:33 load data to database" and
-
00:03:34 database" and watch for the error.
-
00:03:36 watch for the error.
-
00:03:37 watch for the error. Good. So, these uh
-
00:03:39 Good. So, these uh
-
00:03:43 requests were fulfilled. You see that the
-
00:03:44 You see that the completed request is the
-
00:03:45 completed request is the selection of a drug.
-
00:03:46 selection of a drug.
-
00:03:49 Let's see what result it
-
00:03:50 what result it returns. Good. So, the
-
00:03:54 returns. Good. So, the executed query
-
00:03:55 executed query returns this, and then
-
00:03:56 returns this, and then we continue. Okay,
-
00:04:01 we continue. Okay, before
-
00:04:03 before the error occurred, let's
-
00:04:04 the error occurred, let's check what
-
00:04:05 check what queries were executed
-
00:04:06 queries were executed
-
00:04:18 and the error itself. Good.
-
00:04:30 No. Is this the request?
-
00:04:38 Good. Binary data.
-
00:04:47 Good. And let's continue.
-
00:04:56 Good. So this is the next query, and it
-
00:04:57 next query, and it
-
00:05:02 looks like it's on the database itself and it's a
-
00:05:10 database itself and it's a select query
-
00:05:11 select query . Select, select. Is there
-
00:05:14 . Select, select. Is there any
-
00:05:15 any insert request? Good.
-
00:05:43 insert request? Good. App ID Tax TV. There
-
00:05:48 App ID Tax TV. There are no other options. And
-
00:05:50 are no other options. And here is the ID. Yes, here it is
-
00:05:59 here is the ID. Yes, here it is . No. Yes. Okay, it should
-
00:06:14 . No. Yes. Okay, it should be somewhere else
-
00:06:15 be somewhere else , but okay, here it is
-
00:06:23 , but okay, here it is . So, it's here, and you
-
00:06:27 . So, it's here, and you see that this is a
-
00:06:28 see that this is a completed request, and
-
00:06:29 completed request, and then let's see if there
-
00:06:37 then let's see if there 's a message that the
-
00:06:38 's a message that the request
-
00:06:39 request failed, PCR uh PC
-
00:06:44 failed, PCR uh PC completed. Okay, this is an
-
00:06:48 completed. Okay, this is an insert request, and
-
00:06:50 insert request, and it resulted in an
-
00:06:50 it resulted in an error. Yes, I
-
00:06:52 error. Yes, I found her. Okay,
-
00:06:54 found her. Okay, now I see. So, this is
-
00:06:56 now I see. So, this is the name of the program, you
-
00:06:58 the name of the program, you see core Microsoft SQL client
-
00:07:00 see core Microsoft SQL client data provider, and the others are
-
00:07:02 data provider, and the others are Microsoft server management studio.
-
00:07:03 Microsoft server management studio.
-
00:07:06 So we should have checked this from the
-
00:07:07 checked this from the beginning. I
-
00:07:09 beginning. I just figured this out, and
-
00:07:10 just figured this out, and this is exactly the query
-
00:07:11 this is exactly the query that our
-
00:07:13 that our
-
00:07:17 software executed. So let's run this
-
00:07:18 let's run this in, uh, SQL Server Management Studio
-
00:07:22 in, uh, SQL Server Management Studio and see what
-
00:07:23 and see what happens. Okay,
-
00:07:26 happens. Okay, it says: it is impossible
-
00:07:28 it says: it is impossible to insert a duplicate
-
00:07:29 to insert a duplicate key. And why do you
-
00:07:30 key. And why do you think it is
-
00:07:31 think it is duplicated? Because there
-
00:07:33 duplicated? Because there 's something here that caught
-
00:07:35 's something here that caught my eye, and I
-
00:07:36 my eye, and I hope it
-
00:07:37 hope it catches yours too. Here is 025 mg.
-
00:07:43 catches yours too. Here is 025 mg.
-
00:07:43 catches yours too. Here is 025 mg. However, the value here is 0.13
-
00:07:46 However, the value here is 0.13 . Why do you think so?
-
00:07:49 . Why do you think so?
-
00:07:50 . Why do you think so? Because in our
-
00:07:51 Because in our medication table, we didn't
-
00:07:55 medication table, we didn't set the decimal
-
00:07:56 set the decimal precision to 2. We
-
00:08:00 precision to 2. We have to set it to
-
00:08:01 have to set it to at least three, because in
-
00:08:03 at least three, because in our database here
-
00:08:04 our database here it turns out that there are
-
00:08:05 it turns out that there are also, uh, three decimal places
-
00:08:06 also, uh, three decimal places for
-
00:08:07 for milligrams. I don't know
-
00:08:10 milligrams. I don't know if there are also four
-
00:08:10 if there are also four precision marks for
-
00:08:12 precision marks for milligrams. So to
-
00:08:13 milligrams. So to be sure,
-
00:08:14 be sure, you can
-
00:08:15 you can also set four
-
00:08:16 also set four precision marks. So let's
-
00:08:17 precision marks. So let's change that to four
-
00:08:18 change that to four digits of precision. And
-
00:08:22 digits of precision. And let's update our, uh,
-
00:08:23 let's update our, uh,
-
00:08:30 database, uh, classes, I mean
-
00:08:32 I mean PMS classes, using, uh
-
00:08:34 PMS classes, using, uh , EF Power Tools. OK. PMS
-
00:08:43 , EF Power Tools. OK. PMS
-
00:08:45 selected.
-
00:08:56 patient management system. OK.
-
00:09:09 OK. Accuracy increased to
-
00:09:09 increased to four. We
-
00:09:11 four. We can see it too.
-
00:09:12 can see it too. Let me show you.
-
00:09:13 Let me show you. So you see 10 over 4.
-
00:09:19 So you see 10 over 4.
-
00:09:22 Now we shouldn't have this error and
-
00:09:32 have this error and of course, uh, let's insert
-
00:09:34 of course, uh, let's insert more drugs into our
-
00:09:35 more drugs into our table. OK.
-
00:09:40 table. OK.
-
00:10:07 Let's see how
-
00:10:24 the number increases. Okay, still the same. So,
-
00:10:27 still the same. So, obviously there are a lot of
-
00:10:28 obviously there are a lot of duplicate medications
-
00:10:29 duplicate medications
-
00:10:34 or we have an error in the code. Let's check
-
00:10:36 an error in the code. Let's check our code. It seems to have been
-
00:10:41 our code. It seems to have been inside the
-
00:10:42 inside the
-
00:10:47 loading operations. And where is the conversion? here.
-
00:10:52 the conversion? here. Now both
-
00:10:53 Now both look good.
-
00:10:54 look good.
-
00:11:05 OK. You see, every, uh, drug is almost
-
00:11:06 uh, drug is almost duplicated. So they
-
00:11:12 duplicated. So they don't get inserted. We still
-
00:11:14 don't get inserted. We still only inserted
-
00:11:16 only inserted one drug. Oh,
-
00:11:25 one drug. Oh, well, there are over 200,000
-
00:11:27 well, there are over 200,000 drugs, but you see,
-
00:11:31 drugs, but you see, they're all duplicated.
-
00:11:33 they're all duplicated. What value
-
00:11:34 What value is changing? The
-
00:11:35 is changing? The value changes look like
-
00:11:36 value changes look like this. I don't know what they
-
00:11:38 this. I don't know what they mean. Okay,
-
00:11:41 mean. Okay, now there are three of them.
-
00:11:42 now there are three of them. Let's check the
-
00:11:43 Let's check the database to see if
-
00:11:44 database to see if the number has increased. Yes, it
-
00:11:45 the number has increased. Yes, it increased by two,
-
00:11:47 increased by two, as expected.
-
00:11:48 as expected.
-
00:11:51 Okay, we fixed the error. We don't
-
00:11:53 the error. We don't need to wait for them
-
00:11:54 need to wait for them all
-
00:11:55 all to load into the
-
00:11:56 to load into the database. However, it
-
00:11:59 database. However, it works quite fast
-
00:12:01 works quite fast also because we
-
00:12:02 also because we use a
-
00:12:03 use a local cache and yes,
-
00:12:07 local cache and yes, that's it. We have now
-
00:12:09 that's it. We have now fixed the error.
-
00:12:10 fixed the error.
-
00:12:13 Okay, now it's time to add a
-
00:12:14 to add a search function. You see, in
-
00:12:18 search function. You see, in your application, I
-
00:12:19 your application, I also expect that in
-
00:12:20 also expect that in your
-
00:12:22 your homework, in your
-
00:12:23 homework, in your term project
-
00:12:24 term project , there will be a search function,
-
00:12:26 , there will be a search function, search for a book, search for
-
00:12:27 search for a book, search for books or something like that.
-
00:12:28 books or something like that.
-
00:12:33 Good. To be able to search,
-
00:12:34 able to search,
-
00:12:38 let's add a text field.
-
00:12:53 Good. And, let's say, we ask
-
00:12:54 we ask the user to enter
-
00:12:55 the user to enter search terms. Okay
-
00:13:05 search terms. Okay . search and add a
-
00:13:09 . search and add a search button.
-
00:13:10 search button.
-
00:13:25 Good. Search name. Good. Search
-
00:13:29 Good. Search
-
00:13:35 correctly. Good. Good. So, it's going to be a
-
00:13:36 Good. So, it's going to be a search by name and
-
00:13:39 search by name and
-
00:13:46 well, it looks pretty good. Let's add a
-
00:13:48 pretty good. Let's add a click event. And this
-
00:13:51 click event. And this click event
-
00:13:52 click event will simply refresh the
-
00:13:53 will simply refresh the data grid. I'll also add an
-
00:13:59 data grid. I'll also add an
-
00:14:03 Enter key event for this. So,
-
00:14:07 let's also edit the
-
00:14:09 edit the C# click event above. Let's say
-
00:14:31 C# click event above. Let's say , Oh my God. I think the way
-
00:15:05 , Oh my God. I think the way would be to
-
00:15:06 would be to intercept
-
00:15:07 intercept keypress events.
-
00:15:08 keypress events.
-
00:15:15 So, yeah, let's select our form here and
-
00:15:16 our form here and get
-
00:15:17 get keypress events.
-
00:15:19 keypress events.
-
00:15:26 I wonder if this is possible with the tab element's keypress event
-
00:15:27 with the tab element's keypress event
-
00:15:31 . So, this will only apply to
-
00:15:32 only apply to that. I hope so
-
00:15:35 that. I hope so . Yes, there is a
-
00:15:36 . Yes, there is a keystroke. Good. And this is the
-
00:15:39 keystroke. Good. And this is the keystroke
-
00:15:40 keystroke for the medication panel. This is
-
00:15:42 for the medication panel. This is the sender. Got it.
-
00:15:44 the sender. Got it.
-
00:15:46 So, it is not tied to a
-
00:15:47 tied to a
-
00:15:51 specific element . It looks normal,
-
00:15:53 . It looks normal, but I'm not sure.
-
00:15:54 but I'm not sure.
-
00:15:59 So, here we need to check
-
00:16:00 need to check
-
00:16:03 which key
-
00:16:46 was sent. Okay, it looks like this. If the
-
00:16:49 looks like this. If the key data is Enter,
-
00:16:51 key data is Enter,
-
00:16:54 but there is no key data for key events.
-
00:16:55 no key data for key events.
-
00:17:08 Good. that, perhaps,
-
00:17:14 the key perhaps, like this is equal to the
-
00:17:19 equal to the Enter key. Good. And now we're
-
00:17:24 Enter key. Good. And now we're going to simulate
-
00:17:26 going to simulate
-
00:17:30 that. Good. So Enter will also perform
-
00:17:31 will also perform the update. Perfectly.
-
00:17:34 the update. Perfectly.
-
00:17:36 But I don't want it to work in
-
00:17:37 work in other panels. So
-
00:17:40 other panels. So let's see if
-
00:17:41 let's see if we can
-
00:17:42 we can achieve that. This should be
-
00:17:46 achieve that. This should be bound to the
-
00:17:48 bound to the Enter event only in the
-
00:17:53 Enter event only in the medicine panel. Good.
-
00:17:55 medicine panel. Good. Medication tab. And in other
-
00:17:56 Medication tab. And in other panels, when I
-
00:17:57 panels, when I press Enter, it's fine.
-
00:17:59 press Enter, it's fine. Nothing is
-
00:17:59 Nothing is happening. And
-
00:18:01 happening. And nothing
-
00:18:02 nothing happens here.
-
00:18:03 happens here. Normally we should
-
00:18:04 Normally we should tie this to
-
00:18:05 tie this to login, but
-
00:18:06 login, but we haven't done that yet
-
00:18:07 we haven't done that yet . And I
-
00:18:09 . And I will do it for you too. So
-
00:18:16 will do it for you too. So when I press Enter,
-
00:18:17 when I press Enter, nothing
-
00:18:17 nothing happens.
-
00:18:18 happens. Let's
-
00:18:19 Let's tie this in too. Good.
-
00:18:23 tie this in too. Good.
-
00:18:25 in the login panel here. Let's add a
-
00:18:30 here. Let's add a down key event
-
00:18:34 down key event where it is here. Good. And
-
00:18:47 where it is here. Good. And that will just trigger the
-
00:18:48 that will just trigger the login. Click where it is
-
00:18:50 login. Click where it is located. He is here.
-
00:18:52 located. He is here.
-
00:18:57 And let's also add a binding to
-
00:18:59 add a binding to the registration here
-
00:19:02 the registration here selected
-
00:19:03 selected control. Yes. And there is a
-
00:19:08 control. Yes. And there is a
-
00:19:13 keypress event. Good. So you see, in the XML file we
-
00:19:15 see, in the XML file we get the
-
00:19:16 get the keypress event, like this
-
00:19:17 keypress event, like this . So it
-
00:19:19 . So it should only apply to
-
00:19:21 should only apply to this tab and not
-
00:19:22 this tab and not others. And this will simply
-
00:19:26 others. And this will simply be triggered by registration.
-
00:19:31 be triggered by registration. Actually, I wonder if
-
00:19:33 Actually, I wonder if I can just introduce a
-
00:19:34 I can just introduce a
-
00:19:44 registration event.
-
00:19:49 So I mean, right
-
00:19:51 here, let's go to the input um
-
00:19:55 go to the input um , where is this can I
-
00:20:02 , where is this can I do it like this, and will this
-
00:20:03 do it like this, and will this work, will this
-
00:20:10 work, will this shorten our
-
00:20:11 shorten our code behind. Um, I'll
-
00:20:19 code behind. Um, I'll launch the login button
-
00:20:20 launch the login button directly with the
-
00:20:22 directly with the Enter key.
-
00:20:22 Enter key.
-
00:20:31 Let's see. I'll just press Enter. Good. Oh,
-
00:20:37 press Enter. Good. Oh, I have to put a
-
00:20:38 I have to put a stop here. Okay,
-
00:20:43 stop here. Okay, that works. So, we
-
00:20:45 that works. So, we don't even need
-
00:20:46 don't even need this extra
-
00:20:47 this extra unnecessary code. Yeah,
-
00:20:55 unnecessary code. Yeah, with Enter I just...Oh, but
-
00:20:57 with Enter I just...Oh, but that would be...No, no, no.
-
00:20:59 that would be...No, no, no.
-
00:21:02 We can't do it like this. Yes, we
-
00:21:07 it like this. Yes, we need a separate
-
00:21:08 need a separate method because this
-
00:21:09 method because this will be called
-
00:21:10 will be called every time a key is pressed
-
00:21:11 every time a key is pressed . However, I
-
00:21:14 . However, I
-
00:21:17 only need to call it if it's the Enter key. Okay, like this
-
00:21:18 Enter key. Okay, like this
-
00:21:27 . And that will be good. We don't have
-
00:21:28 good. We don't have this KeyDown for the
-
00:21:29 this KeyDown for the top
-
00:21:30 top control. Good. Yes,
-
00:21:38 control. Good. Yes, we don't need KeyDown
-
00:21:39 we don't need KeyDown for the top
-
00:21:40 for the top control.
-
00:21:41 control.
-
00:21:47 You see, you should avoid any
-
00:21:47 any unnecessary code.
-
00:21:49 unnecessary code.
-
00:21:52 Good. So, this is the registration key. And
-
00:22:00 registration key. And in the registers, this is the method
-
00:22:04 in the registers, this is the method we're going to
-
00:22:06 we're going to call. Good.
-
00:22:08 call. Good.
-
00:22:08 call. Good. OK. Now it should
-
00:22:10 OK. Now it should work. Let's
-
00:22:11 work. Let's try. Good.
-
00:22:38 try. Good. Now I'll press Enter.
-
00:22:39 Now I'll press Enter. Yes, it works.
-
00:22:41 Yes, it works. Error. Please
-
00:22:42 Error. Please select a
-
00:22:43 select a user role first.
-
00:22:44 user role first.
-
00:22:45 user role first. Press Enter. Yes,
-
00:22:48 Press Enter. Yes, there was an error.
-
00:22:49 there was an error.
-
00:22:53 Okay, so test Gmail exists. Okay,
-
00:22:56 Gmail exists. Okay, registered and logged in
-
00:22:58 registered and logged in . However,
-
00:23:00 . However, since we
-
00:23:01 since we don't have a patient top menu yet
-
00:23:03 don't have a patient top menu yet , it's still
-
00:23:04 , it's still here. Let's log out
-
00:23:06 here. Let's log out and try
-
00:23:07 and try Enter. Okay, this doesn't
-
00:23:11 Enter. Okay, this doesn't work for the top
-
00:23:12 work for the top login menu yet. So, the
-
00:23:15 login menu yet. So, the
-
00:23:19 top entrance, we did n't add it here. This is the
-
00:23:22 n't add it here. This is the top register, and
-
00:23:27 top register, and
-
00:23:31 this is the top input, and we have a KeyDown, let's
-
00:23:36 we have a KeyDown, let's see if
-
00:23:37 see if it fires. No,
-
00:23:41 it fires. No, registration
-
00:23:41 registration works, but login does
-
00:23:47 works, but login does n't. Why doesn't it
-
00:23:53 n't. Why doesn't it work? Good.
-
00:23:59 work? Good. So, KeyDown for the
-
00:24:00 So, KeyDown for the top element
-
00:24:02 top element fires, but the
-
00:24:08 fires, but the
-
00:24:12 top input. Oh, it works now. Interesting.
-
00:24:14 works now. Interesting.
-
00:24:21 It really works. One
-
00:24:25 works. One second. OK. When
-
00:24:29 second. OK. When I press Enter like this
-
00:24:30 I press Enter like this , it works. But
-
00:24:32 , it works. But if I click somewhere
-
00:24:33 if I click somewhere else, it doesn't
-
00:24:34 else, it doesn't work. I
-
00:24:36 work. I need to be either here
-
00:24:39 need to be either here or inside this.
-
00:24:41 or inside this.
-
00:24:44 So when I click on an empty area, it doesn't
-
00:24:45 empty area, it doesn't work. The event is
-
00:24:48 work. The event is not raised. So the
-
00:24:51 not raised. So the cursor should be either
-
00:24:52 cursor should be either here or here. I think I
-
00:24:58 here or here. I think I can fix that too
-
00:24:59 can fix that too . So
-
00:25:01 . So instead of
-
00:25:02 instead of writing for each one
-
00:25:03 writing for each one individually, I'm going to
-
00:25:04 individually, I'm going to intercept all
-
00:25:05 intercept all click events. Okay
-
00:25:08 click events. Okay . So, I click on the
-
00:25:11 . So, I click on the main window, the
-
00:25:12 main window, the lecture window, and here I
-
00:25:13 lecture window, and here I create a keypress event
-
00:25:14 create a keypress event
-
00:25:16 for the main window.
-
00:25:20 And if the Enter key is pressed, then I'm
-
00:25:21 the Enter key is pressed, then I'm going to use a
-
00:25:25 going to use a switch case construct,
-
00:25:27 switch case construct,
-
00:25:31 but no, I can't use switch, I
-
00:25:33 use switch, I have to use if and
-
00:25:34 have to use if and else if. Okay, what
-
00:25:36 else if. Okay, what tabs do we have? We
-
00:25:38 tabs do we have? We have selected the tab "
-
00:25:39 have selected the tab " drugs". We're
-
00:25:44 drugs". We're going to trigger
-
00:25:46 going to trigger an update for this
-
00:25:47 an update for this tab. Good. Then,
-
00:25:54 tab. Good. Then, if the "login" tab
-
00:25:57 if the "login" tab is selected, we
-
00:25:58 is selected, we 're going to call the
-
00:25:59 're going to call the login like this. And if the
-
00:26:05 login like this. And if the
-
00:26:08 registration tab is selected, we will call this. This will
-
00:26:12 will call this. This will reduce the number of
-
00:26:13 reduce the number of our methods, which I think is
-
00:26:15 our methods, which I think is even better.
-
00:26:16 even better.
-
00:26:24 Now let's remove the keypress events
-
00:26:25 keypress events here, since
-
00:26:26 here, since we've already removed their
-
00:26:27 we've already removed their methods. Good. And
-
00:26:37 methods. Good. And
-
00:26:45 Okay. And and Good. Let's run the program. I'll
-
00:27:10 Let's run the program. I'll click somewhere in the
-
00:27:11 click somewhere in the blank space and
-
00:27:12 blank space and press Enter. Yes, it
-
00:27:14 press Enter. Yes, it works. Let's click
-
00:27:15 works. Let's click here. I click on the
-
00:27:17 here. I click on the empty space. Enter.
-
00:27:19 empty space. Enter.
-
00:27:22 Yes, it works. Okay, let's log out. I
-
00:27:23 let's log out. I click on the empty
-
00:27:25 click on the empty space. Enter. No, it still does
-
00:27:28 space. Enter. No, it still does n't work. Interesting. So
-
00:27:32 n't work. Interesting. So if I make the changes like this
-
00:27:33 if I make the changes like this , now it
-
00:27:35 , now it works. I see
-
00:27:39 works. I see the reason: I can't
-
00:27:40 the reason: I can't click on the empty
-
00:27:42 click on the empty space because this tab is
-
00:27:43 space because this tab is manually selected. But
-
00:27:48 manually selected. But when it
-
00:27:48 when it is selected
-
00:27:49 is selected automatically, it is not
-
00:27:50 automatically, it is not recognized as the
-
00:27:51 recognized as the selected tab. Therefore
-
00:27:54 selected tab. Therefore , when it is selected
-
00:27:55 , when it is selected manually, everything works.
-
00:27:56 manually, everything works. However, if it is
-
00:27:58 However, if it is selected automatically, no
-
00:27:59 selected automatically, no . So,
-
00:28:00 . So, no problems. Everything works as
-
00:28:02 no problems. Everything works as expected. Now let's
-
00:28:04 expected. Now let's go inside. Enter. Perfectly.
-
00:28:07 go inside. Enter. Perfectly.
-
00:28:07 go inside. Enter. Perfectly. Let's go to the
-
00:28:09 Let's go to the "drugs" tab and
-
00:28:10 "drugs" tab and press Enter. Yes,
-
00:28:12 press Enter. Yes, it has been updated. Okay
-
00:28:14 it has been updated. Okay . So, our
-
00:28:16 . So, our key event is now working.
-
00:28:17 key event is now working.
-
00:28:21 By the way, the answer is tied to this
-
00:28:22 tied to this element. I could
-
00:28:25 element. I could bind it to
-
00:28:26 bind it to this or that and it would
-
00:28:27 this or that and it would still work
-
00:28:28 still work when clicking manually.
-
00:28:29 when clicking manually.
-
00:28:33 Now I need to enter a search. OK.
-
00:28:35 enter a search. OK. So, for this
-
00:28:36 So, for this text box,
-
00:28:37 text box,
-
00:28:41 I wonder if they added a
-
00:28:46 placeholder feature. C# placeholders for
-
00:28:47 placeholders for text fields.
-
00:28:48 text fields.
-
00:28:51 Let's see if they added it. This did
-
00:28:54 they added it. This did n't happen before, but it may
-
00:28:55 n't happen before, but it may have. No, it seems there is
-
00:29:02 have. No, it seems there is still no
-
00:29:03 still no
-
00:29:06 easier way.
-
00:29:40 Okay, but there's an XML path that defines
-
00:29:42 path that defines
-
00:29:46 alignment and other things. So, it has a
-
00:29:48 things. So, it has a text block, and the
-
00:29:51 text block, and the text block becomes
-
00:29:53 text block becomes
-
00:29:57 code. I think I'll use this so you
-
00:29:59 use this so you can learn too.
-
00:30:00 can learn too.
-
00:30:03 So, on the " drugs" tab, okay,
-
00:30:11 drugs" tab, okay, let's move on to the
-
00:30:12 let's move on to the text field. So
-
00:30:14 text field. So , inside this
-
00:30:15 , inside this text, under this box,
-
00:30:17 text, under this box, let's edit
-
00:30:18 let's edit -- okay, it's here.
-
00:30:19 -- okay, it's here.
-
00:30:23 So, this will be called
-
00:30:31 uh oh, we don't have a name yet, so that's good.
-
00:30:33 don't have a name yet, so that's good.
-
00:30:41 Let's move this here.
-
00:30:47 Oh, it's just a text field and a
-
00:30:51 field and a placeholder like this, I
-
00:30:55 placeholder like this, I think. Good. Yes,
-
00:30:59 think. Good. Yes, it looks good. And
-
00:31:01 it looks good. And let's add the name
-
00:31:04 let's add the name as a txt search term search by
-
00:31:12 as a txt search term search by name. Good. And
-
00:31:15 name. Good. And let's run
-
00:31:16 let's run the application to
-
00:31:17 the application to check. You see,
-
00:31:20 check. You see, someone else
-
00:31:21 someone else has already asked our
-
00:31:22 has already asked our question exactly the way
-
00:31:23 question exactly the way we wanted. This is why
-
00:31:29 we wanted. This is why search is so important.
-
00:31:30 search is so important.
-
00:31:34 Some of your friends asked me what to do
-
00:31:36 asked me what to do if you can't
-
00:31:37 if you can't
-
00:31:43 continue. The method is the search for answers.
-
00:31:45 is the search for answers.
-
00:31:49 However, I don't see a placeholder. Interesting.
-
00:31:51 placeholder. Interesting. Why? Okay, there's a
-
00:31:56 Why? Okay, there's a text box there.
-
00:31:57 text box there.
-
00:31:58 text box there. Enter your search
-
00:31:59 Enter your search query here and specify the
-
00:32:02 query here and specify the target type—text
-
00:32:04 target type—text block
-
00:32:06 block anchor element. Oh, you see,
-
00:32:08 anchor element. Oh, you see, there's the element name.
-
00:32:09 there's the element name. So, it is bound
-
00:32:11 So, it is bound to the element. Since
-
00:32:14 to the element. Since we changed the name of
-
00:32:15 we changed the name of the text field, we
-
00:32:16 the text field, we need to change the name of the
-
00:32:17 need to change the name of the anchor element
-
00:32:18 anchor element here as well. You see the name of
-
00:32:21 here as well. You see the name of the element here. It should
-
00:32:23 the element here. It should work now. Okay,
-
00:32:46 work now. Okay, now it's visible, and when I
-
00:32:48 now it's visible, and when I click, it should be
-
00:32:49 click, it should be when I click something.
-
00:32:51 when I click something.
-
00:32:54 Yes, it is being cleaned. It
-
00:32:55 Yes, it is being cleaned. It works exactly as we
-
00:32:56 works exactly as we wanted. Press Enter.
-
00:32:58 wanted. Press Enter.
-
00:33:01 Okay, now it's time to implement our
-
00:33:02 to implement our search functions. Search
-
00:33:06 search functions. Search by drug name.
-
00:33:08 by drug name.
-
00:33:21 Okay, let's also change the size to a
-
00:33:22 change the size to a little smaller. That's it.
-
00:33:30 little smaller. That's it.
-
00:33:31 little smaller. That's it. Let's put it in the
-
00:33:32 Let's put it in the center. Good. So in
-
00:33:38 center. Good. So in our
-
00:33:38 our update method we
-
00:33:39 update method we are going to also
-
00:33:40 are going to also include the title and how are
-
00:33:48 include the title and how are we going to
-
00:33:49 we going to do that. Good. So
-
00:33:54 do that. Good. So let's see how we
-
00:33:55 let's see how we do it. There is a
-
00:33:57 do it. There is a
-
00:34:03 local binding list here and that's fine.
-
00:34:04 binding list here and that's fine.
-
00:34:05 binding list here and that's fine. So this is the way
-
00:34:06 So this is the way we download and we
-
00:34:12 we download and we need to add the
-
00:34:15 need to add the
-
00:34:25 search extension. Good. And how can we do that?
-
00:34:26 can we do that? We need to add
-
00:34:28 We need to add something like V.
-
00:34:29 something like V.
-
00:34:37 Okay. and PR. here is
-
00:34:46 the name of the drug and how we can
-
00:34:47 how we can do it, maybe GG is
-
00:34:52 do it, maybe GG is good, does it work,
-
00:34:54 good, does it work, or let's see how it is
-
00:34:58 or let's see how it is possible with Entity Framework, the
-
00:35:00 possible with Entity Framework, the
-
00:35:11 like operator in the framework. How do we
-
00:35:13 framework. How do we do it? Oh, I see, that
-
00:35:22 do it? Oh, I see, that looks like a request. Yes, that's what
-
00:35:24 looks like a request. Yes, that's what we need
-
00:35:26 we need . So contains, okay and
-
00:35:33 . So contains, okay and here we're going to
-
00:35:38 here we're going to add a line. So this is an
-
00:35:41 add a line. So this is an empty symbol. So
-
00:35:43 empty symbol. So everything should contain that. And
-
00:35:47 everything should contain that. And
-
00:35:53 let's see if it works. Let's add to
-
00:35:56 it works. Let's add to the standard or
-
00:36:03 the standard or let's add to
-
00:36:04 let's add to everything here, as if it
-
00:36:05 everything here, as if it works. I have an idea.
-
00:36:08 works. I have an idea.
-
00:36:11 So, this is a dot sort. Good. And
-
00:36:14 dot sort. Good. And
-
00:36:19 this will be an addition like this . it. So,
-
00:36:26 . it. So, first it will
-
00:36:27 first it will organize. I think we
-
00:36:29 organize. I think we need to add a
-
00:36:30 need to add a query first, that would be more
-
00:36:31 query first, that would be more logical, and then
-
00:36:32 logical, and then sort. Yes, that's
-
00:36:36 sort. Yes, that's it. Good. I don't know if
-
00:36:43 it. Good. I don't know if this will work but
-
00:36:44 this will work but we'll see since it's an
-
00:36:46 we'll see since it's an empty string and not
-
00:36:52 empty string and not sure if it
-
00:36:53 sure if it will work or not.
-
00:36:55 will work or not.
-
00:37:10 However, this can also cause
-
00:37:11 cause performance issues.
-
00:37:12 performance issues.
-
00:37:17 Okay, so it works. Perfectly. So what
-
00:37:21 works. Perfectly. So what we're going to
-
00:37:21 we're going to do is, okay, the
-
00:37:30 do is, okay, the SR search term is going to be
-
00:37:31 SR search term is going to be like this, it can't
-
00:37:32 like this, it can't contain null, I'm not going to
-
00:37:34 contain null, I'm not going to do that. Okay, it
-
00:37:46 do that. Okay, it seems to still
-
00:37:47 seems to still work. I'm not
-
00:37:49 work. I'm not sure. Let's
-
00:37:51 sure. Let's try this too.
-
00:37:52 try this too. Maybe this will
-
00:37:53 Maybe this will optimize the database better.
-
00:37:54 optimize the database better.
-
00:38:29 Oh, null doesn't work.
-
00:38:30 Oh, null doesn't work. Let's see
-
00:38:32 Let's see what query it
-
00:38:33 what query it generates. I was thinking about that too
-
00:38:34 generates. I was thinking about that too . So,
-
00:38:38 . So, let's open the SQL Server Provider.
-
00:38:40 let's open the SQL Server Provider.
-
00:38:52 And we'll sort it like this . Good. So, it is
-
00:38:56 . Good. So, it is being done. OK.
-
00:38:59 being done. OK. It says it's of type null.
-
00:39:01 It says it's of type null.
-
00:39:05 Good. And so it essentially checks whether the
-
00:39:07 essentially checks whether the drug name is null or not
-
00:39:08 drug name is null or not . And that's why it doesn't
-
00:39:11 . And that's why it doesn't work. So we'll
-
00:39:13 work. So we'll do it like this. And
-
00:39:14 do it like this. And if the text, by the way,
-
00:39:19 if the text, by the way, comes from this for the
-
00:39:20 comes from this for the main. Have we
-
00:39:29 main. Have we assigned this to something
-
00:39:30 assigned this to something global? Yes.
-
00:39:33 global? Yes.
-
00:39:51 actually greater than zero we'll assign it
-
00:39:54 zero we'll assign it here. Good. And then
-
00:40:00 here. Good. And then here. OK. Let's
-
00:40:06 here. OK. Let's do another search
-
00:40:07 do another search . So, we
-
00:40:09 . So, we use
-
00:40:10 use cascading. However,
-
00:40:13 cascading. However, in reality, if we
-
00:40:15 in reality, if we don't have any
-
00:40:19 don't have any name searches, we shouldn't
-
00:40:20 name searches, we shouldn't
-
00:40:21 use cascading. We would have to, uh,
-
00:40:23 cascading. We would have to, uh, we would have to
-
00:40:31 we would have to program another
-
00:40:32 program another script and
-
00:40:37 script and only add this if
-
00:40:38 only add this if the value is greater.
-
00:40:39 the value is greater.
-
00:40:43 I wonder if that's possible.
-
00:41:05 Yes. OK. And update . Good. It works.
-
00:41:07 . Good. It works.
-
00:41:07 . Good. It works. OK. Let's look at
-
00:41:09 OK. Let's look at the request. So, the request is
-
00:41:11 the request. So, the request is normal. So he
-
00:41:12 normal. So he looks like this. I think
-
00:41:17 looks like this. I think SQL Server would have an
-
00:41:17 SQL Server would have an optimization for
-
00:41:19 optimization for this because when we
-
00:41:20 this because when we search so well,
-
00:41:25 search so well, so it has an OR, so
-
00:41:30 so it has an OR, so let's see
-
00:41:31 let's see how it performs with the
-
00:41:33 how it performs with the
-
00:41:37 execution plan. So it performs a
-
00:41:38 it performs a clustered index
-
00:41:39 clustered index scan. That is, it
-
00:41:44 scan. That is, it scans the entire index, which is
-
00:41:45 scans the entire index, which is very bad
-
00:41:46 very bad
-
00:41:50 because it will take a lot of time. So what
-
00:41:54 a lot of time. So what we need to do
-
00:41:55 we need to do is we need to
-
00:41:58 is we need to create an index as
-
00:42:03 create an index as
-
00:42:06 well, let's open another
-
00:42:07 open another instance to add
-
00:42:08 instance to add the index and the conditional ver.
-
00:42:39 the index and the conditional ver.
-
00:42:42 So I wonder if it's possible, it would improve
-
00:42:43 possible, it would improve our
-
00:42:47 productivity.
-
00:42:57 Good. So we can define the query like this
-
00:42:58 define the query like this , and then we can
-
00:43:03 , and then we can execute the query. Yes.
-
00:43:15 execute the query. Yes. Let's try
-
00:43:16 Let's try this approach. So, he
-
00:43:21 this approach. So, he expects a lot,
-
00:43:23 expects a lot, yes. So what we're
-
00:43:28 yes. So what we're going to do
-
00:43:30 going to do is we're not going to
-
00:43:33 is we're not going to trigger the
-
00:43:34 trigger the load right away,
-
00:43:35 load right away, and if we add it like this
-
00:43:44 and if we add it like this . Good. And
-
00:43:51 . Good. And then we'll load the uh.
-
00:43:52 then we'll load the uh.
-
00:43:59 Let's call the load here. Not
-
00:44:07 the load here. Not sure if it would
-
00:44:08 sure if it would work, but I don't think it would
-
00:44:09 work, but I don't think it would . Yes,
-
00:44:17 . Yes, let's try.
-
00:44:19 let's try. So, let's delete this.
-
00:44:20 So, let's delete this.
-
00:44:23 I hope it works because it will provide
-
00:44:25 because it will provide better performance
-
00:44:26 better performance . Okay, let's
-
00:44:36 . Okay, let's delete that too.
-
00:44:38 delete that too.
-
00:44:45 Okay, let's try.
-
00:44:48 So here we add another predicate to
-
00:44:50 another predicate to ours but it doesn't
-
00:44:56 ours but it doesn't look like a query, I'm not
-
00:45:00 look like a query, I'm not sure if it will
-
00:45:01 sure if it will work. Okay,
-
00:45:20 work. Okay, let's sort by them.
-
00:45:22 let's sort by them.
-
00:45:31 Yes, it doesn't work. So how do we set up a
-
00:45:32 we set up a query and execute it
-
00:45:33 query and execute it ? We use
-
00:45:42 ? We use context, right?
-
00:45:43 context, right?
-
00:46:01 Good. So here is a request.
-
00:46:21 No, that's not the answer we're looking for.
-
00:46:22 we're looking for.
-
00:48:42 Good. Since we are using a
-
00:48:43 are using a local cache and
-
00:48:44 local cache and binding it to the
-
00:48:45 binding it to the
-
00:48:50 data table, it seems like this is not possible. All
-
00:48:53 this is not possible. All this code just returns
-
00:48:55 this code just returns data. They are not
-
00:48:58 data. They are not linkable or
-
00:48:59 linkable or editable in
-
00:49:00 editable in the data table. So, uh
-
00:49:04 the data table. So, uh , they're not what we
-
00:49:08 , they're not what we wanted. Good. So it wo
-
00:49:22 wanted. Good. So it wo n't work that way.
-
00:49:23 n't work that way. Yes. Good.
-
00:49:26 Yes. Good. Let's go back to the
-
00:49:27 Let's go back to the old version. And
-
00:49:36 old version. And here we will add a
-
00:49:37 here we will add a search term and an
-
00:49:38 search term and an index to
-
00:49:39 index to optimize queries
-
00:49:40 optimize queries to the database. I could
-
00:49:48 to the database. I could write different
-
00:49:49 write different switch and case statements,
-
00:49:51 switch and case statements, like default or case
-
00:49:52 like default or case when value is
-
00:49:53 when value is greater, let me
-
00:49:54 greater, let me show you. If
-
00:49:59 show you. If the search term
-
00:50:01 the search term
-
00:50:03 is valid, if the
-
00:50:10 search term is null, like this,
-
00:50:11 is null, like this, otherwise like this. So
-
00:50:14 otherwise like this. So if it's null, it
-
00:50:20 if it's null, it just won't
-
00:50:21 just won't contain it, and if it's not
-
00:50:22 contain it, and if it's not null, it will. This is another
-
00:50:26 null, it will. This is another way to optimize
-
00:50:28 way to optimize your queries. Although the code
-
00:50:30 your queries. Although the code becomes more
-
00:50:31 becomes more cumbersome, it can be
-
00:50:35 cumbersome, it can be optimized
-
00:50:36 optimized anyway, in the end. And I will
-
00:50:45 anyway, in the end. And I will also add an index
-
00:50:46 also add an index to improve
-
00:50:47 to improve performance. How do I
-
00:50:51 performance. How do I do that? Before
-
00:50:54 do that? Before creating the index,
-
00:50:55 creating the index, let's look at
-
00:50:56 let's look at performance.
-
00:50:57 performance.
-
00:51:00 Okay, here it is.
-
00:51:03 It is shown that the approximate number of
-
00:51:05 approximate number of rows is 3500, as well as
-
00:51:10 rows is 3500, as well as the estimated CPU cost
-
00:51:11 the estimated CPU cost and so on. Now let's add
-
00:51:16 and so on. Now let's add an index so that instead of
-
00:51:17 an index so that instead of scanning the index, we do a
-
00:51:18 scanning the index, we do a seek. Good.
-
00:51:22 seek. Good.
-
00:51:23 seek. Good. We don't want to do
-
00:51:24 We don't want to do scans.
-
00:51:25 scans. Scanning means
-
00:51:26 Scanning means looking through the entire
-
00:51:27 looking through the entire index. We need a
-
00:51:29 index. We need a search. OK. Here in
-
00:51:34 search. OK. Here in TBR_drugs, indexes, a new
-
00:51:36 TBR_drugs, indexes, a new non-clustered
-
00:51:37 non-clustered index. So, what
-
00:51:43 index. So, what meaning are we looking for?
-
00:51:47 meaning are we looking for? We are looking for the name of
-
00:51:49 We are looking for the name of the drug. So it
-
00:51:53 the drug. So it comes first, then
-
00:51:54 comes first, then sorting, the
-
00:51:55 sorting, the drug ID is added
-
00:51:56 drug ID is added automatically, and this
-
00:51:57 automatically, and this index is not
-
00:51:58 index is not unique. Although we
-
00:52:03 unique. Although we can make it
-
00:52:05 can make it unique. I think
-
00:52:06 unique. I think
-
00:52:13 the name of the drug is... we already have it as an index
-
00:52:14 we already have it as an index , actually. Let's see.
-
00:52:17 , actually. Let's see.
-
00:52:21 Oh, since we're making a "like" request, it should
-
00:52:23 "like" request, it should come. Yes, there is no
-
00:52:25 come. Yes, there is no other way for,
-
00:52:27 other way for, say, an
-
00:52:27 say, an
-
00:52:32 optimizer to do something different. So he
-
00:52:36 something different. So he has to do
-
00:52:37 has to do a scan, and we
-
00:52:38 a scan, and we already have the name of the medication and the
-
00:52:39 already have the name of the medication and the medication, and so he
-
00:52:43 medication, and so he does a scan of the
-
00:52:44 does a scan of the entire table. Okay,
-
00:52:48 entire table. Okay, let's test
-
00:52:49 let's test our software and see
-
00:52:51 our software and see if the search works.
-
00:52:52 if the search works.
-
00:53:00 Okay, let's update and search for this "proxy
-
00:53:01 search for this "proxy " or something like that. Okay,
-
00:53:07 " or something like that. Okay, now we see all the
-
00:53:09 now we see all the
-
00:53:13 proxies. I don't know how to read that. And then, um
-
00:53:17 read that. And then, um , you see, one
-
00:53:21 , you see, one ends in TA,
-
00:53:23 ends in TA, one in CA. I think we
-
00:53:24 one in CA. I think we can sort by this
-
00:53:26 can sort by this . Yes, it
-
00:53:29 . Yes, it works. Perfectly.
-
00:53:30 works. Perfectly. Let's open this.
-
00:53:32 Let's open this. Introduction. Let's
-
00:53:33 Introduction. Let's search for "milk". Okay
-
00:53:35 search for "milk". Okay . Since our
-
00:53:38 . Since our database is, I believe, case
-
00:53:39 database is, I believe, case insensitive, it
-
00:53:41 insensitive, it should find that too. So
-
00:53:44 should find that too. So this is "milk", and they are also
-
00:53:45 this is "milk", and they are also sorted by
-
00:53:46 sorted by attribute. We
-
00:53:48 attribute. We display
-
00:53:49 display four digits here as a
-
00:53:50 four digits here as a position. So let's
-
00:53:55 position. So let's name by attribute, or
-
00:53:56 name by attribute, or ID by descending or
-
00:53:58 ID by descending or ascending, as you wish
-
00:53:59 ascending, as you wish . Yes, it works exactly as
-
00:54:02 . Yes, it works exactly as we wanted.
-
00:54:04 we wanted.
-
00:54:10 OK. Good. Let's make
-
00:54:11 Let's make notes about what we
-
00:54:12 notes about what we have at the moment
-
00:54:13 have at the moment . And before that, I want to
-
00:54:15 . And before that, I want to rename this to
-
00:54:16 rename this to lecture 10. Okay. Okay
-
00:54:33 lecture 10. Okay. Okay . So, And how to add
-
00:55:15 . So, And how to add search to the context of
-
00:55:19 search to the context of previous work.
-
00:55:20 previous work.
-
00:55:30 Good. How to capture key events throughout the
-
00:55:31 key events throughout the application and
-
00:55:32 application and
-
00:55:40 well. Um, perform actions depending on the
-
00:55:41 actions depending on the
-
00:55:44 selected tab.
-
00:55:49 Good. I think so now.
-
00:56:20 Good. text queries. Yes. Good. And do
-
00:56:32 queries. Yes. Good. And do we have anything else? I think
-
00:56:37 we have anything else? I think
-
00:56:47 key documents or keystrokes.
-
00:56:48 keystrokes.
-
00:56:56 Good. So now we have search,
-
00:56:57 we have search, filtering,
-
00:56:58 filtering, editing, and everything
-
00:56:59 editing, and everything we want. And after
-
00:57:05 we want. And after logging in, I will automatically make
-
00:57:06 logging in, I will automatically make
-
00:57:08 the app go to the medication tab if
-
00:57:09 medication tab if it is a doctor. So let's add
-
00:57:16 it is a doctor. So let's add this, and it'll be
-
00:57:17 this, and it'll be inside our
-
00:57:18 inside our login operations, and you
-
00:57:19 login operations, and you see, we're
-
00:57:19 see, we're setting up the
-
00:57:21 setting up the user's login. Okay,
-
00:57:27 user's login. Okay, before we
-
00:57:28 before we do that, if we
-
00:57:35 do that, if we can log in
-
00:57:36 can log in a user and the user type is
-
00:57:42 a user and the user type is
-
00:57:45 , then what was the type? The
-
00:57:49 user type
-
00:57:58 is set here, and the doctor is two. We
-
00:58:01 doctor is two. We will set the
-
00:58:09 will set the medication tab selected as
-
00:58:12 medication tab selected as true. Good. So
-
00:58:14 true. Good. So let's go in. You
-
00:58:22 let's go in. You see, it's worth
-
00:58:23 see, it's worth trying to make
-
00:58:24 trying to make the app as
-
00:58:25 the app as easy to
-
00:58:26 easy to use as possible for
-
00:58:27 use as possible for your customers or
-
00:58:28 your customers or users. This should
-
00:58:33 users. This should be your goal in
-
00:58:35 be your goal in every case.
-
00:58:36 every case.
-
00:58:45 Good. And now it works. Good. So,
-
00:58:48 works. Good. So, what other screen
-
00:58:49 what other screen could we possibly need? We
-
00:58:56 could we possibly need? We can have prescriptions,
-
00:58:57 can have prescriptions, treatments, and other
-
00:58:59 treatments, and other things according to
-
00:59:00 things according to our needs. However, uh
-
00:59:06 our needs. However, uh I don't think we
-
00:59:09 I don't think we need to
-
00:59:10 need to program these
-
00:59:11 program these screens because they
-
00:59:12 screens because they will be similar. Our
-
00:59:15 will be similar. Our goal here is to learn
-
00:59:16 goal here is to learn as many
-
00:59:17 as many necessary functions as possible.
-
00:59:19 necessary functions as possible.
-
00:59:23 So today I'm also going to show you what it is
-
00:59:25 show you what it is and how it's
-
00:59:25 and how it's used, uh
-
00:59:27 used, uh
-
00:59:32 yield return. Okay. So, what is yield return and how is it
-
00:59:33 is yield return and how is it used?
-
00:59:35 used? So let's
-
00:59:36 So let's get an idea
-
00:59:37 get an idea of what yield return is
-
00:59:39 of what yield return is . Of course, if you have any
-
00:59:51 . Of course, if you have any questions, ask me
-
00:59:52 questions, ask me via Discord so I can
-
00:59:54 via Discord so I can answer your
-
00:59:55 answer your question or
-
00:59:56 question or explain more
-
00:59:57 explain more things in the next
-
00:59:58 things in the next video lecture. Okay,
-
01:00:02 video lecture. Okay, don't forget about it.
-
01:00:04 don't forget about it.
-
01:00:04 don't forget about it. Okay, so understanding
-
01:00:06 Okay, so understanding yield return in C#. Once
-
01:00:16 yield return in C#. Once you understand
-
01:00:17 you understand the use of yield return
-
01:00:18 the use of yield return in C# code, you can't help but
-
01:00:19 in C# code, you can't help but
-
01:00:20 wonder what kind of return form this is or the
-
01:00:22 return form this is or the special mechanism
-
01:00:23 special mechanism for handling it. In
-
01:00:24 for handling it. In the article below, we
-
01:00:25 the article below, we will explore some
-
01:00:27 will explore some programming techniques that
-
01:00:28 programming techniques that involve the
-
01:00:29 involve the yield return keywords in C#.
-
01:00:30 yield return keywords in C#. Quote from MSDN: The
-
01:00:32 Quote from MSDN: The yield keyword signals
-
01:00:33 yield keyword signals to the compiler that the method
-
01:00:35 to the compiler that the method in which it
-
01:00:36 in which it appears is an
-
01:00:37 appears is an iterator block.
-
01:00:38 iterator block.
-
01:00:38 iterator block. The compiler generates a
-
01:00:40 The compiler generates a class to implement
-
01:00:41 class to implement the behavior expressed
-
01:00:42 the behavior expressed in the iterator block. In an
-
01:00:44 in the iterator block. In an iterator block, the
-
01:00:45 iterator block, the yield keyword
-
01:00:46 yield keyword is used
-
01:00:47 is used together with the
-
01:00:48 together with the return keyword to
-
01:00:49 return keyword to return a value to an
-
01:00:50 return a value to an
-
01:00:52 enumeration object. This is the value that
-
01:00:53 the value that is returned,
-
01:00:54 is returned, for example, in each
-
01:00:55 for example, in each loop of a foreach statement. The
-
01:00:57 loop of a foreach statement. The yield keyword
-
01:00:58 yield keyword
-
01:00:59 is also used with break to signal the
-
01:01:01 signal the end of iteration.
-
01:01:02 end of iteration.
-
01:01:04 Okay, let's continue. Iteration,
-
01:01:07 continue. Iteration, one of the yield methods
-
01:01:08 one of the yield methods
-
01:01:10 combined with the return mechanism,
-
01:01:11 return mechanism, allows creation.
-
01:01:12 allows creation. The function returns
-
01:01:14 The function returns a value that
-
01:01:14 a value that processes certain
-
01:01:15 processes certain information in a loop and
-
01:01:17 information in a loop and completes certain conditions
-
01:01:18 completes certain conditions before it. This
-
01:01:19 before it. This contradicts the case of a
-
01:01:21 contradicts the case of a regular return. I
-
01:01:22 regular return. I get the return value of
-
01:01:23 get the return value of
-
01:01:25 the function, which will return and
-
01:01:25 will return and terminate the function at
-
01:01:26 terminate the function at that point. But here
-
01:01:28 that point. But here the function is called
-
01:01:29 the function is called again in the loop
-
01:01:30 again in the loop containing the yield
-
01:01:31 containing the yield return function that just
-
01:01:32 return function that just completed. From here
-
01:01:33 completed. From here we can imagine an action
-
01:01:34 we can imagine an action that is quite
-
01:01:35 that is quite abstract but can
-
01:01:36 abstract but can be useful in
-
01:01:37 be useful in some cases to
-
01:01:38 some cases to help make the
-
01:01:39 help make the code concise and
-
01:01:40 code concise and compact. Two,
-
01:01:41 compact. Two, some requirements for
-
01:01:42 some requirements for using yield return.
-
01:01:44 using yield return. Do not place yield in an
-
01:01:45 Do not place yield in an unsafe block. Do not
-
01:01:47 unsafe block. Do not use the
-
01:01:48 use the ref or
-
01:01:49 ref or out keywords with
-
01:01:50 out keywords with method, operator, or
-
01:01:52 method, operator, or getter/setter accessor parameters. Yield
-
01:01:54 getter/setter accessor parameters. Yield return can be placed
-
01:01:55 return can be placed in a try block only if it
-
01:01:57 in a try block only if it is followed by a finally block.
-
01:01:58 is followed by a finally block.
-
01:01:59 is followed by a finally block. Yield break can be
-
01:02:00 Yield break can be placed in a try
-
01:02:01 placed in a try and catch block, but cannot be
-
01:02:02 and catch block, but cannot be placed in a
-
01:02:04 placed in a finally block. Do not
-
01:02:06 finally block. Do not use yield in an
-
01:02:07 use yield in an anonymous method.
-
01:02:08 anonymous method.
-
01:02:10 Three, an example of using yield return.
-
01:02:12 using yield return.
-
01:02:14 To use yield return, simply
-
01:02:16 yield return, simply create a method with an
-
01:02:17 create a method with an
-
01:02:19 IEnumerable return type; Arrays and collections in .NET
-
01:02:20 collections in .NET implement the
-
01:02:22 implement the IEnumerable interface using a
-
01:02:23 IEnumerable interface using a loop and yield return to
-
01:02:24 loop and yield return to return values in the
-
01:02:26 return values in the loop body. Here is an
-
01:02:28 loop body. Here is an example of a function with
-
01:02:29 example of a function with two arguments, int
-
01:02:31 two arguments, int start and int number, that
-
01:02:32 start and int number, that creates even numbers
-
01:02:33 creates even numbers starting from a given
-
01:02:34 starting from a given value. Below
-
01:02:36 value. Below is the code
-
01:02:37 is the code written in the usual
-
01:02:38 written in the usual way, where
-
01:02:39 way, where the result
-
01:02:40 the result is returned as an
-
01:02:41 is returned as an array, and then we
-
01:02:42 array, and then we use the array
-
01:02:43 use the array to retrieve
-
01:02:44 to retrieve the result.
-
01:02:44 the result. Instead, we can
-
01:02:46 Instead, we can use yield return
-
01:02:47 use yield return to simplify the code,
-
01:02:48 to simplify the code, speed up the work,
-
01:02:49 speed up the work, and reduce the cost
-
01:02:50 and reduce the cost of intermediate
-
01:02:51 of intermediate structures. This
-
01:02:51 structures. This makes it easier to check for
-
01:02:53 makes it easier to check for errors in the code when
-
01:02:53 errors in the code when working with large
-
01:02:54 working with large amounts of data.
-
01:02:55 amounts of data. OK. So, we have a
-
01:02:57 OK. So, we have a few
-
01:02:58 few code snippets. Let's
-
01:02:59 code snippets. Let's create our example
-
01:03:00 create our example from scratch to better
-
01:03:02 from scratch to better understand everything. I'll create an
-
01:03:07 understand everything. I'll create an additional, uh,
-
01:03:08 additional, uh,
-
01:03:15 console project. We will make an example of
-
01:03:16 make an example of using yield return
-
01:03:18 using yield return to better
-
01:03:23 to better understand it. Okay, I'm
-
01:03:34 understand it. Okay, I'm choosing a console
-
01:03:36 choosing a console application. This is .NET Core.
-
01:03:38 application. This is .NET Core.
-
01:03:41 Further. So, let's name it, let's name it as
-
01:03:45 it, let's name it as
-
01:03:56 we choose the folder for the lectures, Lectures10_cmd, and
-
01:03:57 lectures, Lectures10_cmd, and let's name it like this,
-
01:03:59 let's name it like this, next. You see, .NET 5,
-
01:04:07 next. You see, .NET 5, the latest .NET Core.
-
01:04:09 the latest .NET Core.
-
01:04:13 OK. So the function here essentially does
-
01:04:15 here essentially does an addition, or let's
-
01:04:20 an addition, or let's see what it
-
01:04:21 see what it does? There is an array that
-
01:04:24 does? There is an array that has a length of 10, and there is
-
01:04:28 has a length of 10, and there is a function that adds the
-
01:04:30 a function that adds the start value and other
-
01:04:36 start value and other things. Let's
-
01:04:38 things. Let's write it. So,
-
01:04:41 write it. So, let's create our array as
-
01:04:43 let's create our array as int a, like this. The
-
01:04:48 int a, like this. The
-
01:04:53 integer array a is equal to a new
-
01:04:54 is equal to a new integer array
-
01:04:55 integer array of size 10. Now
-
01:05:01 of size 10. Now we have a function
-
01:05:03 we have a function like public static
-
01:05:08 like public static integer array, myFunction,
-
01:05:11 integer array, myFunction, or whatever name,
-
01:05:13 or whatever name,
-
01:05:18 method. So, this method takes start and number. And,
-
01:05:37 takes start and number. And, actually, it
-
01:05:38 actually, it initializes a new
-
01:05:39 initializes a new temporary array like this
-
01:05:41 temporary array like this . OK.
-
01:05:51 . OK. Integers, size 10.
-
01:05:53 Integers, size 10.
-
01:05:53 Integers, size 10. Where does this
-
01:05:54 Where does this number 10 come from? It
-
01:05:56 number 10 come from? It comes from above. Oh,
-
01:05:57 comes from above. Oh, this is an array declaration
-
01:05:59 this is an array declaration with
-
01:06:00 with number elements, not 10.
-
01:06:01 number elements, not 10.
-
01:06:04 And using a for loop, starting from zero
-
01:06:08 for loop, starting from zero to number, it assigns
-
01:06:15 to number, it assigns the value to the array like this
-
01:06:17 the value to the array like this : i is equal to start
-
01:06:21 : i is equal to start
-
01:06:29 plus 2 times i, and then it returns this
-
01:06:31 and then it returns this array. OK. And then
-
01:06:45 array. OK. And then we'll write a line,
-
01:06:46 we'll write a line, right? Of course.
-
01:06:48 right? Of course. Of course. So,
-
01:06:50 Of course. So, let's assign a the result of
-
01:06:51 let's assign a the result of executing myMethod with
-
01:06:54 executing myMethod with arguments 2 and 10, and
-
01:06:59 arguments 2 and 10, and then we can
-
01:07:00 then we can use a foreach loop
-
01:07:01 use a foreach loop
-
01:07:06 on the array and Console.WriteLine, printing
-
01:07:12 Console.WriteLine, printing item. Let's see what this
-
01:07:15 item. Let's see what this will print, because this is a very
-
01:07:16 will print, because this is a very basic function, it will
-
01:07:17 basic function, it will print the numbers
-
01:07:18 print the numbers assigned to the array.
-
01:07:20 assigned to the array.
-
01:07:28 Good. 2, 4, 6, 8, 10, 12, 14, 16, 18 and 20. Yes. since
-
01:07:38 18 and 20. Yes. since we are adding zero, we
-
01:07:40 we are adding zero, we start with two: 2 + 0,
-
01:07:42 start with two: 2 + 0, then 2 + 2, then 2 + 4, 2 +
-
01:07:44 then 2 + 2, then 2 + 4, 2 + 6, and so on. So,
-
01:07:52 6, and so on. So, now
-
01:07:54 now we will
-
01:07:54 we will use yield
-
01:07:56 use yield return instead. Okay, how
-
01:07:59 return instead. Okay, how can we do this? Yield
-
01:08:04 can we do this? Yield return returns a
-
01:08:05 return returns a value during
-
01:08:07 value during each iteration.
-
01:08:08 each iteration.
-
01:08:09 each iteration. Of course. So
-
01:08:13 Of course. So basically we're going to change
-
01:08:14 basically we're going to change this code like this: for
-
01:08:19 this code like this: for each one we're going to create
-
01:08:21 each one we're going to create another method. This
-
01:08:25 another method. This method will return
-
01:08:26 method will return integers and
-
01:08:30 integers and
-
01:08:34 in fact it should return yes, it
-
01:08:39 return yes, it should also return an
-
01:08:40 should also return an enumerator
-
01:08:42 enumerator . And this will be the yield method.
-
01:08:49 . And this will be the yield method.
-
01:08:50 . And this will be the yield method. Good. So, essentially,
-
01:08:53 Good. So, essentially,
-
01:08:58 instead of an array here, we'll have something like
-
01:08:59 we'll have something like this. Yield return.
-
01:09:03 this. Yield return.
-
01:09:11 OK. And it should pay off. Good.
-
01:09:13 pay off. Good. They say, so this is a different
-
01:09:16 They say, so this is a different type of iterator.
-
01:09:17 type of iterator.
-
01:09:18 type of iterator. Let's do it as
-
01:09:24 Let's do it as integers. Okay, this is
-
01:09:30 integers. Okay, this is n't a type of enumerator either.
-
01:09:32 enumerator either.
-
01:09:35 Got it. So, it simply returns an
-
01:09:36 simply returns an IEnumerable, not any
-
01:09:38 IEnumerable, not any
-
01:09:48 specific type. Okay , I needed to
-
01:09:49 , I needed to add system
-
01:09:50 add system collections. So
-
01:09:54 collections. So instead of
-
01:09:55 instead of assigning it like that,
-
01:09:56 assigning it like that, now I just
-
01:09:57 now I just need to call "
-
01:09:59 need to call " 2 to 10" and output
-
01:10:08 2 to 10" and output another loop from 2 to 10.
-
01:10:10 another loop from 2 to 10.
-
01:10:14 foreach, and I'll call yield return and it'll take 2 and 10
-
01:10:20 return and it'll take 2 and 10
-
01:10:26 and then console.writeline item.
-
01:10:31 You can see how much simpler and
-
01:10:32 simpler and easier the code becomes. Let's also
-
01:10:38 easier the code becomes. Let's also put a
-
01:10:39 put a stop here. And here too.
-
01:10:44 stop here. And here too.
-
01:10:47 Okay, let's do it. A step, and
-
01:10:49 do it. A step, and we see
-
01:10:50 we see a two on the screen. The two
-
01:10:52 a two on the screen. The two are removed. We do it.
-
01:10:54 are removed. We do it.
-
01:11:01 Oh, this... I don't know why this error occurs,
-
01:11:03 this error occurs, but it does occur on my
-
01:11:03 but it does occur on my computer
-
01:11:04 computer . When
-
01:11:07 . When I iterate with
-
01:11:08 I iterate with debugging, this
-
01:11:09 debugging, this happens. So,
-
01:11:10 happens. So, you see, it prints the same thing
-
01:11:11 you see, it prints the same thing . However, this is not
-
01:11:15 . However, this is not returned directly
-
01:11:16 returned directly from the foreach loop method.
-
01:11:17 from the foreach loop method.
-
01:11:20 It returns the value and continues the
-
01:11:21 the value and continues the loop. So this
-
01:11:23 loop. So this value comes
-
01:11:24 value comes in here, and then we
-
01:11:25 in here, and then we use it like this
-
01:11:26 use it like this . Of course.
-
01:11:28 . Of course. This is what yield return is.
-
01:11:30 This is what yield return is. If you do
-
01:11:31 If you do another example
-
01:11:32 another example yourself, you will
-
01:11:33 yourself, you will be able to understand this better
-
01:11:34 be able to understand this better . I am
-
01:11:35 . I am sure of this. This
-
01:11:37 sure of this. This can be very
-
01:11:37 can be very useful in various
-
01:11:39 useful in various cases. So, that's all
-
01:11:45 cases. So, that's all . I think this is a much
-
01:11:47 . I think this is a much better option,
-
01:11:48 better option, easier to understand,
-
01:11:49 easier to understand, and probably more
-
01:11:50 and probably more effective. Now
-
01:11:54 effective. Now we've gotten rid of the
-
01:11:55 we've gotten rid of the array definition
-
01:11:56 array definition here or the
-
01:11:57 here or the array definition here, and so on.
-
01:12:01 array definition here, and so on.
-
01:12:05 Good. So, what topic should we
-
01:12:06 topic should we continue with? Let me
-
01:12:08 continue with? Let me think about it. Okay,
-
01:12:15 think about it. Okay, let's continue
-
01:12:16 let's continue working with
-
01:12:17 working with multithreading
-
01:12:18 multithreading to understand it better
-
01:12:19 to understand it better . So after that,
-
01:12:25 . So after that, I'll clean the screen.
-
01:12:26 I'll clean the screen.
-
01:12:33 Good. Command console dot
-
01:12:39 clear. Good. So, with multithreading, a
-
01:12:41 multithreading, a
-
01:12:47 race condition arises. Okay. Therefore, to effectively
-
01:12:48 to effectively use
-
01:12:49 use multithreading,
-
01:12:50 multithreading, you need to
-
01:12:51 you need to synchronize the
-
01:12:52 synchronize the threads. What does this mean?
-
01:12:56 threads. What does this mean? Let me show you.
-
01:12:58 Let me show you.
-
01:13:01 Let's say I have a number of type double. The
-
01:13:04 number of type double. The double type is not atomic.
-
01:13:05 double type is not atomic. So this should be
-
01:13:07 So this should be fine. Example:
-
01:13:08 fine. Example: DBL count. Okay. And
-
01:13:16 DBL count. Okay. And let's say I have a
-
01:13:17 let's say I have a method like this
-
01:13:18 method like this that increments a number. And
-
01:13:31 that increments a number. And it just loops,
-
01:13:33 it just loops, let's say, up to 10,000,
-
01:13:34 let's say, up to 10,000, increments the counter
-
01:13:35 increments the counter by one. So, we'll
-
01:13:40 by one. So, we'll get we'll do it like this
-
01:13:44 get we'll do it like this . Yes. Okay. This
-
01:13:48 . Yes. Okay. This will give us, by the way, this
-
01:13:49 will give us, by the way, this should also be
-
01:13:50 should also be static. Okay. So that would
-
01:13:59 static. Okay. So that would give us 10,000,
-
01:14:01 give us 10,000, right? And if I
-
01:14:02 right? And if I call it twice, what
-
01:14:04 call it twice, what happens? That's right
-
01:14:08 happens? That's right , it'll be 20,000,
-
01:14:09 , it'll be 20,000, right. So
-
01:14:13 right. So let's do some
-
01:14:18 let's do some console output too.
-
01:14:19 console output too.
-
01:14:26 Okay. The expected value is 20,000.
-
01:14:27 value is 20,000.
-
01:14:30 The value we got is: okay. and a
-
01:14:36 got is: okay. and a line with the
-
01:14:37 line with the counter value and zero.
-
01:14:41 counter value and zero.
-
01:14:45 Okay, let's see if it shows up like this
-
01:14:46 it shows up like this . So, the expected
-
01:14:50 . So, the expected value is 20,000, and the
-
01:14:52 value is 20,000, and the received value is 10,000. What
-
01:14:56 received value is 10,000. What if I call these
-
01:14:57 if I call these numbers at the same time? How to
-
01:14:59 numbers at the same time? How to do it? I can
-
01:15:00 do it? I can do this
-
01:15:01 do this using task.factory.
-
01:15:02 using task.factory. factory and to
-
01:15:07 factory and to use it,
-
01:15:08 use it, you need to add a
-
01:15:09 you need to add a reference to threading tasks
-
01:15:11 reference to threading tasks start new. Okay, it
-
01:15:14 start new. Okay, it looks like this.
-
01:15:15 looks like this.
-
01:15:21 Okay, I'll run two separate tasks here like this
-
01:15:22 two separate tasks here like this and paste them in here
-
01:15:27 and paste them in here . I can even
-
01:15:29 . I can even run multiple
-
01:15:30 run multiple tasks. Let's run
-
01:15:32 tasks. Let's run four tasks. That's
-
01:15:36 four tasks. That's it. Okay. So what would
-
01:15:40 it. Okay. So what would the expected
-
01:15:41 the expected value be now?
-
01:15:42 value be now?
-
01:15:43 value be now? The expected value
-
01:15:45 The expected value would be 60,000. Right? And
-
01:15:47 would be 60,000. Right? And let's see what
-
01:15:48 let's see what value we
-
01:15:49 value we get. By the way, this
-
01:15:50 get. By the way, this will use
-
01:15:52 will use four cores
-
01:15:52 four cores at once. So I
-
01:15:54 at once. So I expect full
-
01:15:55 expect full
-
01:15:59 CPU usage. Okay.
-
01:16:02 However, we received 50,000 . Why exactly 10 thousand
-
01:16:13 . Why exactly 10 thousand less? Let's
-
01:16:21 less? Let's see when we
-
01:16:22 see when we comment it out and
-
01:16:23 comment it out and do it like this. You
-
01:16:34 do it like this. You see, we get
-
01:16:36 see, we get 60,000. However, when we
-
01:16:39 60,000. However, when we run the task, we
-
01:16:40 run the task, we get 50,000. It
-
01:16:43 get 50,000. It could be even
-
01:16:44 could be even less or a different number.
-
01:16:45 less or a different number.
-
01:16:53 So, essentially, a race condition arises. Let
-
01:16:54 race condition arises. Let
-
01:16:54 race condition arises. Let 's run it without
-
01:16:55 's run it without debugging. You see,
-
01:16:58 debugging. You see, this time we
-
01:16:59 this time we got 30,000. So the
-
01:17:05 got 30,000. So the same threads, or
-
01:17:06 same threads, or let's say different threads,
-
01:17:08 let's say different threads, are trying to change
-
01:17:09 are trying to change the number at the same time, and a
-
01:17:10 the number at the same time, and a
-
01:17:17 race condition occurs. What was it called? call
-
01:17:20 called? call it a database change
-
01:17:21 it a database change
-
01:17:25 if I remember correctly. Okay, so
-
01:17:32 remember correctly. Okay, so this is the state of the
-
01:17:33 this is the state of the stream race. Okay,
-
01:17:38 stream race. Okay, let's actually
-
01:17:40 let's actually read this.
-
01:17:47 read this. Race conditions in
-
01:17:48 Race conditions in multithreading C.
-
01:17:50 multithreading C. Good.
-
01:17:56 Introduction. A race condition occurs when two or
-
01:17:58 occurs when two or more threads
-
01:17:59 more threads access
-
01:18:00 access shared data and
-
01:18:01 shared data and attempt to modify
-
01:18:02 attempt to modify it at the same time.
-
01:18:03 it at the same time.
-
01:18:04 it at the same time. Since the
-
01:18:05 Since the thread scheduling algorithm
-
01:18:06 thread scheduling algorithm can switch
-
01:18:07 can switch between them at any
-
01:18:08 between them at any moment, we cannot
-
01:18:09 moment, we cannot know the order of
-
01:18:10 know the order of access to shared
-
01:18:11 access to shared data. Therefore, the result of
-
01:18:14 data. Therefore, the result of changing data depends
-
01:18:15 changing data depends on the
-
01:18:16 on the scheduling algorithm, i.e.
-
01:18:17 scheduling algorithm, i.e. threads compete for
-
01:18:18 threads compete for access to data or
-
01:18:19 access to data or its modification. The reason
-
01:18:22 its modification. The reason why race conditions
-
01:18:23 why race conditions occur more often in
-
01:18:24 occur more often in threads than in
-
01:18:25 threads than in processes is
-
01:18:26 processes is that threads
-
01:18:27 that threads share shared
-
01:18:27 share shared memory, while processes do not
-
01:18:29 memory, while processes do not . For example,
-
01:18:32 . For example, suppose we have
-
01:18:34 suppose we have two threads T1 and T2
-
01:18:35 two threads T1 and T2 accessing a
-
01:18:36 accessing a common variable X.
-
01:18:38 common variable X. They read data and
-
01:18:39 They read data and then try
-
01:18:41 then try to write it
-
01:18:41 to write it simultaneously. They
-
01:18:44 simultaneously. They compete to see
-
01:18:45 compete to see which thread writes the
-
01:18:46 which thread writes the value last. In
-
01:18:48 value last. In this case,
-
01:18:49 this case, the last recorded value will be saved
-
01:18:50 the last recorded value will be saved . As
-
01:18:53 . As another example,
-
01:18:54 another example, consider a situation
-
01:18:55 consider a situation where threads T1 and T2
-
01:18:56 where threads T1 and T2 perform opposite
-
01:18:58 perform opposite operations on this
-
01:18:59 operations on this variable. Let thread
-
01:19:01 variable. Let thread T1 increase the value
-
01:19:03 T1 increase the value of the variable, and thread T2
-
01:19:04 of the variable, and thread T2 decrease it at the
-
01:19:06 decrease it at the same point in time.
-
01:19:07 same point in time.
-
01:19:09 What is the result?
-
01:19:10 What is the result? The value will remain
-
01:19:11 The value will remain unchanged. Good. You
-
01:19:15 unchanged. Good. You see the problem,
-
01:19:16 see the problem, let me explain.
-
01:19:17 let me explain.
-
01:19:25 OK. Let's say we have , uh, stream A. Uh,
-
01:19:27 , uh, stream A. Uh, okay. Let me
-
01:19:30 okay. Let me write this down. So,
-
01:19:32 write this down. So, suppose thread A
-
01:19:35 suppose thread A
-
01:19:44 or thread one reads a variable as 200, increments it
-
01:19:45 variable as 200, increments it by one, and stores
-
01:19:47 by one, and stores . So, at the same
-
01:19:53 . So, at the same moment, let thread
-
01:19:57 moment, let thread two access the
-
01:19:58 two access the variable, read it as
-
01:20:02 variable, read it as 200, increment it by
-
01:20:03 200, increment it by one, and store it.
-
01:20:05 one, and store it.
-
01:20:11 So, uh, thread one saves first, and the
-
01:20:12 saves first, and the value becomes 2001, but
-
01:20:14 value becomes 2001, but at the same moment
-
01:20:22 at the same moment thread two saves, and
-
01:20:24 thread two saves, and it becomes 2001 again,
-
01:20:26 it becomes 2001 again, instead of 2002. So how do we
-
01:20:31 instead of 2002. So how do we prevent that? We
-
01:20:37 prevent that? We need to
-
01:20:38 need to use
-
01:20:39 use lock. With
-
01:20:41 lock. With locking, only
-
01:20:42 locking, only one thread can
-
01:20:43 one thread can access an
-
01:20:44 access an element at a given
-
01:20:45 element at a given time. Good. So
-
01:20:59 time. Good. So how do we do it?
-
01:21:00 how do we do it?
-
01:21:01 how do we do it? Let me show you.
-
01:21:02 Let me show you.
-
01:21:05 First, I'll set the value of our
-
01:21:06 the value of our variable to zero here.
-
01:21:07 variable to zero here.
-
01:21:15 Good. Then I will use another
-
01:21:16 use another method with blocking,
-
01:21:17 method with blocking,
-
01:21:24 increasing numbers with synchronization.
-
01:21:25 synchronization.
-
01:21:30 Okay, let me check the
-
01:21:31 check the
-
01:21:38 spelling. Oh, I spelled that correctly.
-
01:21:39 spelled that correctly. Wow. Good. And for this
-
01:21:43 Wow. Good. And for this to work, we
-
01:21:44 to work, we need another object
-
01:21:46 need another object or we can just
-
01:21:47 or we can just call log. But I
-
01:21:49 call log. But I will show you the
-
01:21:49 will show you the right way. This
-
01:21:53 right way. This may look like ` lock
-
01:21:55 may look like
lock b count, or no, it -
01:21:57 b count`, or no, it cannot be locked because
-
01:21:59 cannot be locked because it is not a reference type.
-
01:22:01 it is not a reference type.
-
01:22:04 Therefore, we need a link. Okay, private
-
01:22:06 link. Okay, private static object. We
-
01:22:10 static object. We use object
-
01:22:11 use object because it is
-
01:22:12 because it is the smallest
-
01:22:12 the smallest reference type to
-
01:22:13 reference type to lock double and we
-
01:22:18 lock double and we need to
-
01:22:19 need to initialize it
-
01:22:20 initialize it as a new object. Good. And we
-
01:22:24 as a new object. Good. And we will block it. We
-
01:22:25 will block it. We will block the double
-
01:22:27 will block the double every time
-
01:22:27 every time we are going to increment
-
01:22:29 we are going to increment its value. Good.
-
01:22:30 its value. Good.
-
01:22:31 its value. Good. And we can do
-
01:22:32 And we can do it like this. Good. And
-
01:22:37 it like this. Good. And now I'll use the
-
01:22:38 now I'll use the part with
-
01:22:39 part with synchronization.
-
01:22:40 synchronization.
-
01:22:50 Good. This time we call
-
01:22:51 call synchronization. Good.
-
01:23:02 synchronization. Good.
-
01:23:05 synchronization, which has methods
-
01:23:05 methods using lock and
-
01:23:12 using lock and this time I'll even
-
01:23:14 this time I'll even call more
-
01:23:15 call more threads at the same time, and
-
01:23:16 threads at the same time, and let's see what we
-
01:23:17 let's see what we get, well, the
-
01:23:23 get, well, the expected value of
-
01:23:25 expected value of 80,000, and what we got,
-
01:23:26 80,000, and what we got, what we're going to
-
01:23:27 what we're going to get is actually,
-
01:23:29 get is actually, of course, locking
-
01:23:30 of course, locking is, uh, a resource-intensive
-
01:23:35 is, uh, a resource-intensive process. I mean it
-
01:23:36 process. I mean it consumes
-
01:23:38 consumes resources. So this
-
01:23:40 resources. So this slows down your
-
01:23:41 slows down your program a little bit. Okay,
-
01:23:42 program a little bit. Okay, this time we
-
01:23:43 this time we got zero and why is that
-
01:23:49 got zero and why is that
-
01:24:01 interesting. This is definitely not something I've seen before
-
01:24:02 I've seen before . Okay, let's take
-
01:24:15 . Okay, let's take a look. Oh, I know the
-
01:24:32 a look. Oh, I know the reason. I know the
-
01:24:33 reason. I know the reason. Good. Oh,
-
01:24:35 reason. Good. Oh, what was the reason? Do
-
01:24:38 what was the reason? Do you think we
-
01:24:39 you think we made the same
-
01:24:40 made the same mistake here? These
-
01:24:43 mistake here? These tasks are performed
-
01:24:44 tasks are performed immediately. So when we
-
01:24:47 immediately. So when we read the values
-
01:24:48 read the values here, they are still
-
01:24:49 here, they are still being executed. So,
-
01:24:52 being executed. So, I also need to
-
01:24:53 I also need to wait for the running
-
01:24:54 wait for the running tasks. And how will I
-
01:24:56 tasks. And how will I do that? I'm going to
-
01:24:57 do that? I'm going to do this
-
01:24:58 do this with Okay,
-
01:25:00 with Okay, let's write it
-
01:25:01 let's write it here. Okay, when we
-
01:25:06 here. Okay, when we read data here, the
-
01:25:07 read data here, the tasks are still
-
01:25:08 tasks are still running. Therefore, we do
-
01:25:15 running. Therefore, we do not get the
-
01:25:16 not get the final volume. So,
-
01:25:20 final volume. So,
-
01:25:24 therefore, we need to make sure that the
-
01:25:25 make sure that the tasks are completed. And
-
01:25:28 tasks are completed. And how are we going to
-
01:25:29 how are we going to do that? We're
-
01:25:30 do that? We're going to do
-
01:25:31 going to do this using a
-
01:25:32 this using a list. By the way, to
-
01:25:35 list. By the way, to be able to
-
01:25:36 be able to use
-
01:25:37 use the list, I need to
-
01:25:38 the list, I need to add another
-
01:25:39 add another reference, namely
-
01:25:40 reference, namely collections generic tasks
-
01:25:46 collections generic tasks and LST started tasks equals
-
01:25:48 and LST started tasks equals new tasks. Okay, what I'm
-
01:25:54 new tasks. Okay, what I'm going to do
-
01:25:56 going to do is task. When you
-
01:25:57 is task. When you run a task
-
01:25:59 run a task with start name, it
-
01:25:59 with start name, it returns the expected
-
01:26:01 returns the expected task. And I'll just
-
01:26:03 task. And I'll just add this task
-
01:26:04 add this task here. Task. Good. Then
-
01:26:11 here. Task. Good. Then I'm going to call
-
01:26:13 I'm going to call LST tasks and then wait all I
-
01:26:26 LST tasks and then wait all I think to be
-
01:26:27 think to be able to
-
01:26:28 able to do that we had
-
01:26:29 do that we had something else, a collection
-
01:26:31 something else, a collection or I think. Good. How do
-
01:26:51 or I think. Good. How do I do this?
-
01:26:52 I do this?
-
01:27:01 Let's find it. Let's take a look. Okay,
-
01:27:13 a look. Okay, yes, task wait all. Okay,
-
01:27:15 yes, task wait all. Okay, now I remember. So
-
01:27:19 now I remember. So we use task
-
01:27:21 we use task dot wait all, and wait all
-
01:27:22 dot wait all, and wait all takes, you see, an
-
01:27:23 takes, you see, an array of tasks, which is
-
01:27:25 array of tasks, which is our ls started tasks, and we
-
01:27:26 our ls started tasks, and we need to convert
-
01:27:28 need to convert it into an array. Okay,
-
01:27:33 it into an array. Okay, now the program
-
01:27:38 now the program will wait for
-
01:27:39 will wait for all tasks to complete
-
01:27:40 all tasks to complete . But that
-
01:27:48 . But that still doesn't prevent the
-
01:27:49 still doesn't prevent the database. Good. And
-
01:27:54 database. Good. And now we need to
-
01:27:55 now we need to do the same for
-
01:27:56 do the same for other tasks. So we'll
-
01:28:00 other tasks. So we'll add that here too. Okay
-
01:28:07 add that here too. Okay . And then we
-
01:28:09 . And then we call the same thing
-
01:28:10 call the same thing
-
01:28:14 when the previous tasks are complete.
-
01:28:15 tasks are complete.
-
01:28:18 So, using the same
-
01:28:20 list won't affect our productivity
-
01:28:21 our productivity or anything else. And
-
01:28:25 or anything else. And let's look
-
01:28:26 let's look at the results. Okay
-
01:28:28 at the results. Okay , this time we
-
01:28:29 , this time we got 60,000, and the
-
01:28:34 got 60,000, and the data race condition didn't
-
01:28:36 data race condition didn't occur with the double type.
-
01:28:37 occur with the double type.
-
01:28:40 Actually, this is somewhat unexpected. Maybe
-
01:28:43 unexpected. Maybe we should run
-
01:28:44 we should run this without debugging.
-
01:28:46 this without debugging.
-
01:28:46 this without debugging. Yes. So, during
-
01:28:49 Yes. So, during debugging, it
-
01:28:50 debugging, it ran
-
01:28:51 ran slow enough to
-
01:28:52 slow enough to increment all
-
01:28:53 increment all values independently.
-
01:28:54 values independently.
-
01:28:57 However, when we run the program
-
01:28:58 run the program without debugging, you
-
01:29:00 without debugging, you see that it becomes
-
01:29:01 see that it becomes faster, but still not
-
01:29:02 faster, but still not
-
01:29:05 accurate. So let's increase the number of
-
01:29:07 increase the number of our tasks.
-
01:29:07 our tasks.
-
01:29:13 number of tasks and see what we
-
01:29:14 see what we get. Oh, we have to
-
01:29:16 get. Oh, we have to get 100,000 right
-
01:29:18 get 100,000 right now. And what do we
-
01:29:21 now. And what do we get? Okay,
-
01:29:23 get? Okay, now there are more tasks
-
01:29:24 now there are more tasks than he can handle
-
01:29:26 than he can handle . So we
-
01:29:28 . So we only get this. However,
-
01:29:30 only get this. However, using
-
01:29:31 using blocking, we always
-
01:29:33 blocking, we always get 80,000. We
-
01:29:38 get 80,000. We can even
-
01:29:39 can even increase the number of
-
01:29:40 increase the number of tasks to something
-
01:29:42 tasks to something really high, like 20, and
-
01:29:43 really high, like 20, and we should get
-
01:29:45 we should get 200,000, here we'll do 20, and we
-
01:29:46 200,000, here we'll do 20, and we should get 200,000.
-
01:29:47 should get 200,000.
-
01:29:54 Of course, this will make the program consume
-
01:29:55 the program consume more CPU
-
01:29:57 more CPU time, but it
-
01:30:07 time, but it still computes
-
01:30:08 still computes too fast. Oho. Oh
-
01:30:10 too fast. Oho. Oh , we still get
-
01:30:12 , we still get everything. So let's
-
01:30:13 everything. So let's run it without
-
01:30:14 run it without debugging. Good.
-
01:30:16 debugging. Good. And we got it. But
-
01:30:18 And we got it. But every time we will always
-
01:30:19 every time we will always receive 200,000.
-
01:30:21 receive 200,000.
-
01:30:24 Got it? So, when you're
-
01:30:25 you're multitasking, you
-
01:30:26 multitasking, you always have to uh,
-
01:30:30 always have to uh,
-
01:30:32 synchronize the threads with each other. You
-
01:30:34 threads with each other. You should always have
-
01:30:35 should always have synchronization between
-
01:30:36 synchronization between threads. Okay, this is a
-
01:30:37 threads. Okay, this is a very important rule.
-
01:30:39 very important rule.
-
01:30:43 Never forget that without synchronization
-
01:30:44 that without synchronization between threads, you will not
-
01:30:45 between threads, you will not get
-
01:30:45 get deterministic
-
01:30:46 deterministic results. Good.
-
01:30:49 results. Good.
-
01:30:55 if it were, there's another way too, and
-
01:30:57 another way too, and if it wasn't a double, but
-
01:30:58 if it wasn't a double, but let's say a static long
-
01:31:00 let's say a static long , and a long like this zero,
-
01:31:08 , and a long like this zero, I could
-
01:31:08 I could synchronize it
-
01:31:09 synchronize it without any
-
01:31:10 without any blocking. How could I
-
01:31:14 blocking. How could I do that? I could
-
01:31:17 do that? I could do this
-
01:31:18 do this with Interlocked.
-
01:31:19 with Interlocked.
-
01:31:25 Good. By the way, Interlocked also requires threading,
-
01:31:30 also requires threading, like this. We added
-
01:31:35 like this. We added threading, as you can see, and
-
01:31:37 threading, as you can see, and Interlocked, and then increment.
-
01:31:38 Interlocked, and then increment.
-
01:31:42 So this is a thread-safe
-
01:31:43 thread-safe operation, and as long as you
-
01:31:44 operation, and as long as you use
-
01:31:45 use Interlocked for everything, it
-
01:31:46 Interlocked for everything, it will be thread-safe
-
01:31:48 will be thread-safe . It provides atomic
-
01:31:51 . It provides atomic operations on variables
-
01:31:52 operations on variables that are shared across
-
01:31:53 that are shared across multiple threads.
-
01:31:54 multiple threads.
-
01:31:57 Atomic means it will happen
-
01:31:58 it will happen
-
01:32:01 in a single cycle. Good. So what does an
-
01:32:03 So what does an atomic operation mean? This
-
01:32:12 atomic operation mean? This means it
-
01:32:13 means it will happen in
-
01:32:15 will happen in one processor
-
01:32:16 one processor cycle, if I
-
01:32:16 cycle, if I remember correctly.
-
01:32:18 remember correctly.
-
01:32:28 The atom is indivisible.
-
01:32:29 The atom is indivisible. Atomic operations
-
01:32:30 Atomic operations are indivisible
-
01:32:31 are indivisible operations that
-
01:32:32 operations that cannot be divided.
-
01:32:33 cannot be divided.
-
01:32:35 Example: Interrupted microprocessors do not
-
01:32:37 microprocessors do not execute
-
01:32:37 execute sequentially, that is,
-
01:32:38 sequentially, that is, instruction by
-
01:32:39 instruction by instruction, as
-
01:32:40 instruction, as written in the program.
-
01:32:41 written in the program.
-
01:32:44 There are external objects that can
-
01:32:45 objects that can change the course of
-
01:32:46 change the course of execution. A good
-
01:32:48 execution. A good example is
-
01:32:49 example is interruption. So, you
-
01:32:51 interruption. So, you may know the
-
01:32:52 may know the instruction set that is
-
01:32:53 instruction set that is available on almost
-
01:32:54 available on almost all processors.
-
01:32:55 all processors.
-
01:32:56 all processors. Imagine it
-
01:32:57 Imagine it being executed by a
-
01:32:58 being executed by a processor. A 32-bit
-
01:33:00 processor. A 32-bit value
-
01:33:01 value is moved into a 32-
-
01:33:02 is moved into a 32- bit register. Now
-
01:33:04 bit register. Now , after shifting 16
-
01:33:06 , after shifting 16 bits, an interrupt request occurs
-
01:33:07 bits, an interrupt request occurs . The
-
01:33:08 . The
-
01:33:11 atomic instruction will not stop, but
-
01:33:12 will not stop, but will execute to the end,
-
01:33:13 will execute to the end, and only then will the processor
-
01:33:14 and only then will the processor handle the interrupt
-
01:33:16 handle the interrupt . A non-
-
01:33:18 . A non- atomic instruction will be
-
01:33:19 atomic instruction will be immediately stopped and an
-
01:33:20 immediately stopped and an
-
01:33:22 interrupt will be executed.
-
01:33:23 interrupt will be executed. The problem is that
-
01:33:24 The problem is that if the interrupt
-
01:33:25 if the interrupt accesses
-
01:33:26 accesses the register that
-
01:33:27 the register that the data was written to,
-
01:33:28 the data was written to, the result will be
-
01:33:29 the result will be unclear
-
01:33:30 unclear because the operation is
-
01:33:31 because the operation is only
-
01:33:32 only half complete. Typically,
-
01:33:34 half complete. Typically, on conventional
-
01:33:35 on conventional processors, operations
-
01:33:36 processors, operations with processor word size
-
01:33:37 with processor word size are
-
01:33:38 are atomic. If the
-
01:33:40 atomic. If the processor word is
-
01:33:41 processor word is 16 bits wide, a 16-bit
-
01:33:43 16 bits wide, a 16-bit instruction will be
-
01:33:44 instruction will be atomic. However, a 32-
-
01:33:47 atomic. However, a 32- bit operation
-
01:33:48 bit operation will not be atomic. Such a
-
01:33:53 will not be atomic. Such a non-atomic
-
01:33:53 non-atomic instruction
-
01:33:55 instruction is usually provided not by an
-
01:33:56 is usually provided not by an instruction set, but by a
-
01:33:57 instruction set, but by a high-level language like C,
-
01:33:59 high-level language like C, where operations like long
-
01:34:00 where operations like long long or long do not
-
01:34:01 long or long do not guarantee
-
01:34:02 guarantee atomicity. OK.
-
01:34:05 atomicity. OK.
-
01:34:06 atomicity. OK. So you understand
-
01:34:07 So you understand the problem, since we
-
01:34:09 the problem, since we are incrementing a
-
01:34:10 are incrementing a double precision number
-
01:34:12 double precision number , which is 64
-
01:34:13 , which is 64 bits if I
-
01:34:14 bits if I remember correctly.
-
01:34:15 remember correctly.
-
01:34:18 Let's check the size of a double or,
-
01:34:20 the size of a double or, say, the size of a C#double.
-
01:34:21 say, the size of a C#double.
-
01:34:26 Oh, it's eight bytes, which means it has
-
01:34:29 which means it has 64 bits. Yes. Therefore, in a 32-
-
01:34:34 64 bits. Yes. Therefore, in a 32- bit program, this would
-
01:34:35 bit program, this would take two operations.
-
01:34:37 take two operations.
-
01:34:40 OK. And it will never be atomic.
-
01:34:41 be atomic.
-
01:34:45 To be sure that your operation is
-
01:34:46 that your operation is atomic, you must
-
01:34:47 atomic, you must use
-
01:34:48 use increment. This will make
-
01:34:55 increment. This will make it atomic
-
01:34:56 it atomic programmatically; it can
-
01:34:58 programmatically; it can take ref as well as
-
01:34:59 take ref as well as long or int 32. Now it
-
01:35:05 long or int 32. Now it will increment the value
-
01:35:06 will increment the value by one. You
-
01:35:07 by one. You can also set how
-
01:35:11 can also set how much
-
01:35:11 much to increment.
-
01:35:13 to increment.
-
01:35:16 In fact, it all increments by
-
01:35:17 increments by one. There is also add or
-
01:35:20 one. There is also add or other functions that you
-
01:35:22 other functions that you see like add.
-
01:35:24 see like add. With add you
-
01:35:25 With add you can add
-
01:35:27 can add any value you
-
01:35:28 any value you want and it will be
-
01:35:29 want and it will be atomic. OK. So
-
01:35:32 atomic. OK. So let's put
-
01:35:33 let's put this in here and see
-
01:35:34 this in here and see what value we
-
01:35:35 what value we get. So we'll
-
01:35:38 get. So we'll get 10,000, 20,000 and
-
01:35:41 get 10,000, 20,000 and okay, let's
-
01:35:47 okay, let's write that down here.
-
01:35:48 write that down here.
-
01:35:50 The expected value for a long with atomicity,
-
01:35:56 for a long with atomicity, when I say auto or
-
01:35:57 when I say auto or interlock, okay, and the
-
01:36:05 interlock, okay, and the value we
-
01:36:06 value we get is a long,
-
01:36:07 get is a long, let's see
-
01:36:08 let's see what that is. So even
-
01:36:13 what that is. So even if we don't do
-
01:36:14 if we don't do any synchronization
-
01:36:16 any synchronization with lock, it should always
-
01:36:17 with lock, it should always be 200k, which is
-
01:36:21 be 200k, which is 220,000, and yes, that's exactly right.
-
01:36:23 220,000, and yes, that's exactly right.
-
01:36:26 You see, double doesn't work like that, but interlock does
-
01:36:28 that, but interlock does . So this is
-
01:36:31 . So this is another way, if you
-
01:36:32 another way, if you are working with
-
01:36:34 are working with integers or long,
-
01:36:35 integers or long, use
-
01:36:36 use interlocked. This can be
-
01:36:37 interlocked. This can be used for
-
01:36:38 used for reading or many
-
01:36:40 reading or many other things. Let
-
01:36:40 other things. Let 's take a look. So, it
-
01:36:42 's take a look. So, it supports addition,
-
01:36:43 supports addition, increment, swap, or
-
01:36:45 increment, swap, or decrement. Okay, with
-
01:36:52 decrement. Okay, with addition you can
-
01:36:53 addition you can also use
-
01:36:54 use subtraction with
-
01:36:55 subtraction with negative
-
01:36:55 negative values, and exchange
-
01:36:56 values, and exchange means it
-
01:36:57 means it sets the value of
-
01:36:59 sets the value of something. OK. So it's
-
01:37:04 something. OK. So it's thread-safe.
-
01:37:06 thread-safe.
-
01:37:14 OK. So let's write that down too.
-
01:37:15 write that down too.
-
01:37:21 OK. What is yield return and how to
-
01:37:22 return and how to use it?
-
01:37:23 use it?
-
01:37:29 OK. Example return.
-
01:37:33 OK. What is the chase state when
-
01:37:36 chase state when
-
01:37:40 you are multitasking?
-
01:37:42 multitasking?
-
01:37:50 OK. How to prevent a race condition
-
01:37:51 race condition with mm
-
01:37:54 with mm
-
01:38:01 synchronization by using a
-
01:38:02 using a
-
01:38:09 blocking methodology. OK.
-
01:38:16 How can we use
-
01:38:17 use
-
01:38:23 interlock to ensure that our
-
01:38:25 ensure that our operations on
-
01:38:26 operations on int32 or long
-
01:38:28 int32 or long int64 variables are
-
01:38:35 int64 variables are
-
01:38:38 thread-safe.
-
01:38:39 thread-safe. OK. How to achieve
-
01:38:54 OK. How to achieve security when working with
-
01:38:56 security when working with many threads.
-
01:38:57 many threads.
-
01:39:06 OK. And what else do we have related to
-
01:39:07 related to
-
01:39:24 this, okay? So in this case,
-
01:39:25 this case, no error occurs.
-
01:39:26 no error occurs.
-
01:39:36 However, if we were working with
-
01:39:37 were working with lists, such as
-
01:39:38 lists, such as appending to lists
-
01:39:39 appending to lists or enumerating
-
01:39:40 or enumerating them, while simultaneously
-
01:39:41 them, while simultaneously doing something else in
-
01:39:42 doing something else in another thread, it
-
01:39:43 another thread, it could cause
-
01:39:45 could cause the program to crash due to
-
01:39:46 the program to crash due to an error. Or so it is,
-
01:40:01 an error. Or so it is,
-
01:40:05 okay. Next semester, of course, we'll
-
01:40:06 semester, of course, we'll cover more
-
01:40:07 cover more topics related to
-
01:40:08 topics related to multithreading and
-
01:40:09 multithreading and more. If you have
-
01:40:13 more. If you have specific questions or
-
01:40:14 specific questions or topics you would like to
-
01:40:15 topics you would like to see covered, please
-
01:40:17 see covered, please contact me
-
01:40:18 contact me or leave a comment
-
01:40:19 or leave a comment below the video so
-
01:40:20 below the video so I
-
01:40:21 I can cover it in the next lecture. In the
-
01:40:26 can cover it in the next lecture. In the next lecture, I
-
01:40:27 next lecture, I plan to write a
-
01:40:28 plan to write a crawler, a simple web
-
01:40:29 crawler, a simple web crawler, to do
-
01:40:31 crawler, to do more multitasking and
-
01:40:32 multitasking and other operations. And
-
01:40:36 other operations. And
-
01:40:44 okay, so we're almost done; we
-
01:40:45 done; we showed a lot of
-
01:40:46 showed a lot of things, okay? And
-
01:40:50 things, okay? And
-
01:40:57 okay, I think we'll finish this week
-
01:40:58 we'll finish this week . And okay,
-
01:41:06 . And okay, let's upload
-
01:41:08 let's upload our source code to
-
01:41:11 our source code to
-
01:41:16 GitHub. I didn't do the other
-
01:41:19 patient management system screens because they would be the same as the
-
01:41:20 they would be the same as the medication panel. You
-
01:41:28 medication panel. You could
-
01:41:29 could use other
-
01:41:30 use other elements like
-
01:41:31 elements like combo boxes, text
-
01:41:32 combo boxes, text fields, you already know them
-
01:41:34 fields, you already know them . These fields all work
-
01:41:36 . These fields all work on the same
-
01:41:37 on the same methodology. OK.
-
01:41:40 methodology. OK.
-
01:42:18 OK. OK. End of the 10th lecture.
-
01:42:20 End of the 10th lecture. Hope to see
-
01:42:21 Hope to see you next week.
