Chapter 13. Advanced Topics

In Chapter 12, Performance, we studied application's performance under several points of view and analyzed some of the most meaningful tools at our disposal in order to improve our software's response time.

This chapter covers advanced concepts, mainly related to three areas. So, you can consider it a miscellaneous chapter, addressing several topics that either do not fit directly within the context of any of the preceding chapters or are too new, such as what happens with .NET Core.

Specifically, I will cover how an application can receive system's calls in its own functions and also explain how our code can integrate and communicate with the OS using its APIs.

Another topic we will cover is Windows Management Instrumentation (WMI) and how it allows the developer to access and modify critical aspects of the system, which are sometimes difficult to reach in other approaches.

We'll also cover parallelism, analyzing some myths and misunderstandings of these topics and testing these approaches so that we can really evaluate the advantages of this type of programming.

The chapter ends with an introduction to .NET Core 1.0 and its derivative work, ASP.NET Core 1.0, and its implications and meaning in the open source programming world, along with some examples of how to use it. The availability of this technology was made public by the end of June, 2016, and some minor additions were included in version 1.1, mainly bug fixes and coverage for more operating systems.

So, we're going to start with the mechanisms that allow communication between the OS and .NET in both directions. But first, it would be interesting to remember the basics of how the operating system works internally and, specifically, how it manages messages between windows if we really want to understand and take advantage of this feature in the .NET code.

To summarize, we will cover the following topics in this chapter:

  • Sub-classing and platform/invoke
  • Windows Management Instrumentation
  • Extended techniques in parallel programming
  • An introduction to .NET Core 1.0 and ASP.NET Core 1.0

The Windows messaging subsystem

All Windows-based applications are event-driven. This means that they don't make explicit calls to functions in the OS APIs. Instead, they wait for the system to pass any input to them. So it's the system that's the one in charge of providing that input.

The system's kernel is in charge of converting hardware events (users' clicks, keyboard entries, touch screen gestures, the arrival of bytes in a communication's port, and so on) into software events, which take the form of messages addressed to a software target: a button in a window, a textbox in a form, and so on. After all, this is the soul of the Event-driven Programming paradigm.

I'll start with a section that deals with how .NET can use low-level resources of the operating system, in other words, how our applications can communicate and use the core functionality of our operating system, despite being coded using distinct models, with distinct data types and calling conventions. This technique permits .NET applications to use resources in Windows that are not mapped directly to CLR classes and integrate that functionality into our applications.

The MSG structure

A message is nothing but a numeric code that uniquely identifies a particular event. For example, for the previous case when the user presses the left mouse button, the window receives a message with this message code: 0x0201. This number is previously defined in code in the following way:

#define WM_LBUTTONDOWN    0x0201

Some messages have data associated with them. For example, in this case, the WM_LBUTTONDOWN message has to indicate the x coordinate and y coordinate of the mouse cursor to the programmer.

Whenever a message is passed to a window, the operating system calls a special function of that window, called the window procedure, which is registered for that window at creation time.

This is because in Windows, everything is a window (well, almost), and every window procedure (called WndProc) takes care of the messages it receives as soon as the system sends some input for that window. Actually, the messages are queued, and the system has the ability to promote some messages in the queue thanks to a priority policy.

All aspects of a window's appearance (and behavior) depend on the window procedure's response to these messages.

Tip

Remember, a window is anything that the system distinguishes with a handler: a unique number that makes that component different from the rest. That is, buttons, icons, among others, are just windows embedded in other windows, each one with its own handler.

So, every time you click on a button, pass the cursor over an icon or use Ctrl + C to copy the content, and system sends a message to the target window (the button, the icon, the clipboard, and so on).

A message is received by the wndproc function associated with that target, which processes that message and returns control to the system.

The following figure shows this structure in more detail:

The MSG structure

Note that according to the MSDN:

"If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding. In this case, the system hides the window and replaces it with a ghost window that has the same Z order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually not responding. When in the debugger mode, the system does not generate a ghost window."

As mentioned earlier, either system messages or user messages are queued and the wndproc function processes them in a first-in-first-out fashion (with some exceptions).

Actually, you can distinguish between two kinds of messages: those sent by user applications, which generally go to the FIFO queue, and others, sent by the OS which can have a distinct priority and, therefore, can be located before the rest in the queue (for example, error messages).

These messages can be sent via Post Message or Send Message APIs depending on the expected behavior, and although we're not going to cover these aspects in depth (since they go far beyond the scope of this chapter), we'll look at how we can send messages using these APIs and what we can obtain through this technique.

The next figure shows how all this happens from different threads in the system:

The MSG structure

Our applications, though managed, behave the same way, and the fact that we can access handles from our code makes it possible to capture events from the system and change behaviors at will.

Among these techniques, the one that allows us to capture system or application events is called sub-classing. Let's explain how it works and how we can use it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.244.250