Monday, August 08, 2005

BeginInvoke Method

BeginInvoke Method

BeginInvoke is a method of Control, and it executes a delegate asynchronously on the thread that the control's underlying handle was created on.

Sunday, August 07, 2005

How virtual Memory works?

The virtual memory system allows only part of the memory required by the process to be resident in physical memory. Say, if a process requires 500 mb memory, but it may only have 20% memory sitting in physical memory, the other 80% may actually stay on the disk.

Demand Paging

1>When a process requests a block of memory, it check the internal page table for this process to determine whether the reference was a valid or invalid memory access.
2>If the reference is invalid, we terminate the process. If it was valid, but we have not yet brought in that page, we now page it in.
3>We find a free frame by taking one from the free-frame list.
4>We schedule a disk operation to read the desired page into the new allocated frame.
5>When the disk operation is complete, we modify the internal table kept with the process and the page table to indicate that the page is now in memory.
6>We restart the instruction that was interrupted by the illegal address trap.

Paging

1>Paging allows the logically continuous memory to be scattered through the physical memory out of order.
2>Suppose the logical address space is 2**m, and the page size is 2**n, then the high order m-n bits are designated as page number, while the lower n bits are designated as offset after the particular physical page has been found.
3>The TLB is the quick look up to speed up the page table translation, it will quickly find the entry for the logical address. If the TLB is missing, then we need to look up the page table to find the right entry.
4>If the logical address space is very large, and the page size is relatively small, it will lead to a very large page table. We have to use a couple of techniques such as "multi level page table", "inverted page table" to reduce the size.

Finalizer and Disposer

Finalizer is an implict cleanup, which relies on the GC to clean up the resources, while the disposer is explicit cleanup, which allows to clean up the resources explictly. The .Net supports both patterns, so it is very important to distinguish them. In general, explicit cleanup should be used favorably over the implict cleanup, since the resources are generally more precious than memory, we shouldn't really rely on the GC to hold it for long time and clean it after an unspecified time.

Annotation (Brian Grunkemeyer): There are two different concepts that are somewhat intertwined around object tear-down. The first is the end of the lifetime of a resource (such as a Win32 file handle), and the second is the end of the lifetime of the object holding the resource (such as an instance of FileStream). Unmanaged C++ provided destructors which ran deterministically when an object left scope, or when the programmer called delete on a pointer to an object. This would end the resource’s lifetime, and at least in the case of delete, end the lifetime of the object holding onto the resource. The CLR’s finalization support only allows you to run code at the end of the lifetime of the object holding a resource. Relying on finalization as the sole mechanism for cleaning up resources extends the resource’s lifetime to be equal to the lifetime of the object holding the resource, which can lead to problems if you need exclusive access to that resource or there are a finite number of them, and can hurt performance. Hence, witness the Dispose pattern for managed code, allowing you to define a method to explicitly mimic the determinism & eagerness of destructors in C++. This relegates finalization to a backstop against users of a type who do not call Dispose, which is a good thing considering the additional restrictions on finalizers.

In the Dispose(bool disposing) method, if the diposing passed in is true, it means that we can explicitely use other reference types that refer to other objects knowing for sure that those other objects have not been finalized or disposed yet. If it's false, we cannot refer to other resources since those objects may have already been freed.

When we inherit a class which has already correctly implemented "IDispose" pattern, we need only override the Dispose (bool disposing) class, we don't need to override the Finalize and Dipose class.

Saturday, August 06, 2005

Internal Fragmentation and External Fragmentation.

In the memory allocation model, if the memory is partitioned into the fixed size blocks[M bytes a block], then when a process(N bytes) is allocated into the memory, it will fit the first N/M blocks, and occupy the part of the last block, and this is called "internal fragmentation", since the fragment is internal to a block.

The other model is called "external fragmentation", the memory is NOT partitioned into the fixed size. It will maintain a free list of "available" memory blocks and select the best fit for the waiting process. The fragment is external to any occupied blocks so it is called external fragmentation.

Wednesday, August 03, 2005

What is delegate in C#

Delegate is a class, NOT a method. It is a class inherited from System.Delegate or System.MulticastDelegate, which has two properties called "Target" and "Method". The target is the class instance on which the current delegate invokes the instance method, if it is null, it means it's a "Static" calling. MethodInvoker or EventHander are two special delegates treated in a fast manner by Invoke and BeginInvoke. MethodInvoker takes no parameters and returns no value, and EventHandler takes two parameters and returns no value.

Notifications

Notifications

It takes me a while to figure out why the legend control is not updated correctly until I found this sentence.

The applications that rely solely on WM_VSCROLL (and WM_HSCROLL) for scroll position data have a practical maximum position value of 65,535.


The GetScrollInfo function enables applications to use 32-bit scroll positions. Although the messages that indicate scroll-bar position, WM_HSCROLL and WM_VSCROLL, provide only 16 bits of position data, the functions SetScrollInfo and GetScrollInfo provide 32 bits of scroll-bar position data. Thus, an application can call GetScrollInfo while processing either the WM_HSCROLL or WM_VSCROLL messages to obtain 32-bit scroll-bar position data.

To get the 32-bit position of the scroll box (thumb) during a SB_THUMBTRACK message in a WM_HSCROLL or WM_VSCROLL message, call GetScrollInfo with the SIF_TRACKPOS value in the fMask member of the SCROLLINFO structure. The function returns the tracking position of the scroll box in the nTrackPos member of the SCROLLINFO structure. This allows you to get the position of the scroll box as the user moves it. The following sample code illustrates the technique.

SCROLLINFO si;
case WM_HSCROLL:
switch(LOWORD(wparam)) {
case SB_THUMBTRACK:
// Initialize SCROLLINFO structure

ZeroMemory(&si, sizeof(SCROLLINFO));
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_TRACKPOS;

// Call GetScrollInfo to get current tracking
// position in si.nTrackPos

if (!GetScrollInfo(hwnd, SB_HORZ, &si) )
return 1; // GetScrollInfo failed
break;
.
.
.
}