CLR via C# (4th Edition) (Developer Reference)

Category: Programming
Author: Jeffrey Richter
4.3
All Stack Overflow 22
This Month Stack Overflow 5

Comments

by anonymous   2019-07-21

As @craig-w mentions, there's a very small compile time performance improvement.

The way that the compiler works, is when it encounters a type, it looks in the current namespace, and then starts searching each namespace with a using directive in the order presented until it finds the type it's looking for.

There's an excellent writeup on this in the book CLR Via C# by Jeffrey Richter (http://www.amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/ref=sr_1_1?ie=UTF8&qid=1417806042&sr=8-1&keywords=clr+via+c%23)

As to why MS provided the menu option, I would imagine that enough internal developers were asking for it for the same reasons that you mention: cleaner, more concise code.

by user5057257   2019-07-21

Short Answer:
The trick to be able to use Async I/O with Duplex WCF Contract is the following simple code:

    [OperationContract(IsOneWay = true)]
    Task OnPushData(data);

Simply you need to change the return type of your callback contract method to be Task. but this is not enough, you need to implement an async method like this:

    public async Task PublishData()
    {
        communicationCallback = (ICommunicationObject)service.Callback;
        if (communicationCallback.State == CommunicationState.Opened)
        {
                await service.Callback.OnPushData(data);
        }
    }

That is all. This actually boosts the performance of my application. and Now I am able to see I/O completion Ports threads utilized calling ThreadPool.GetAvailableThreads(workers,IO)

Some Explinations:
As I understand, to be able to use Async I/O mechanism, you will need to do the following:

1- Determining your I/O operation.
2- A method that will encapsulate your async I/O logic.
3- A callback mechanism that will be called when async I/O is finished and its purpose mainly is to get the result of the Async I/O.
4- An object that will holds your Async I/O result.

.NET framework provides 3 design patterns to do so:

1- IAsyncResult Asynchrnous Pattern: where Beginxxx and Endxxx will encapsulate your async logic along with a Callback Delegate that represents the callback method and of course an IAsyncResult object used to hold your async I/O result.
2- Task Based Asynchronous Pattern: Using one class only which is Task along with async/await keywords that facilitate the using of TAP pattern.
3- Event Based Asynchronous Pattern.

You can read more about how you can use these patterns with WCF Services at How to Implement an Asynchronous Service Operation

However, The previous link is great for implementing async request/response service, though, there is no explanation on how to do so with callback contract.
Unfortunately, in my case I have to implement a subscriber/publisher patttern using WCF framework where data publishing is initiated by the service side periodically (each 1 second).

More Details:
I will try to make this as short as possible:
WCF is relying on ThreadPool provided by .NET Framework. ThreadPool has 2 kind of threads:
1- Worker Threads: for Compute-Bound operations.
2- I/O Completion Port Threads: Used to get the result of an I/O operation.

You must differentiate between IOCP Thread and IOCP Object initiated by CLR. IOCP Thread role is to deliver the result of I/O operation while IOCP Object is the one initiated by CLR to recieve all I/O requests. In other words, they collaborate to achieve I/O operation.

First thing you need to know is that any I/O request you made will result in a system call that will initiate an object Called IRP (I/O request Packet) whether you are using synchronous or asynchronous paradigm.

I/O Completion Port (IOCP) is nothing but a queue-like object initiated by the CLR. This object is responsible for receiving all I/O Completed requests (IRPs). At this point there are 2 possibilities here:
1- Your I/O operation is called by a synchronous method: In this case the caller thread will be blocked until your I/O operation is done.
2- Your I/O operation is called by an async method: In this case the caller thread will continue the execution and it will not be blocked for the I/O operation until completion.

Supposing that you are using async method, When your async I/O operation is completed, this means the IRP object is processed and now it will be queued to IOCP object. ThreadPool IOCP threads will come to play the role of pulling the relative IRP from IOCP which will be wrapped in IAsyncResult for APM or Task object for TAP and passing this object to your application Level through a Callback Mechanism.

Some References:

[1]: https://msdn.microsoft.com/en-us/library/ms734701.aspx
[2]: http://blog.stephencleary.com/2012/08/async-wcf-today-and-tomorrow.html
[3]: http://southworks.com/blog/2013/10/29/asynchronous-io-in-c-io-completion-ports/
[4]: http://southworks.com/blog/2013/08/02/asynchronous-io-in-c-introduction/
[5]: http://mikehadlow.blogspot.com/2011/03/7000-concurrent-connections-with.html
[6]: https://msdn.microsoft.com/en-us/library/ms731177(v=vs.110).aspx
[7]: http://www.amazon.es/Clr-Via-C-Developer-Reference/dp/0735667454

by anonymous   2019-07-21

This answer lies within how long your tasks take to execute. As explained in CLR via C# by Jeffrey Richter (I highly recommend this book), if your task takes more than about a 5th of a second to execute, the windows operating system will have to context switch. In high throughput environments, context switching is considered an expensive operation.

If all of your methods execute within ~200 ms, separating your you method calls into individual tasks may be superfluous. Unless, of course, you need some of the task scheduling options as mentioned in another post.

http://www.amazon.com/CLR-via-C-Developer-Reference/dp/0735667454

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682105(v=vs.85).aspx

by bold_monkey   2018-01-25
It depends on your goals, if you want a deep understandigyou must learn ho CLR works:

This book can be a good start: > https://www.amazon.com/CLR-via-4th-Developer-Reference/dp/07...

Anyway, if you have specific needs, the knowledge needed may vary. For LOB applications (IMHO) very often performance issue have to be searched in I/O (RDMS / WebServices / RPC), these times in all depends a lot on query tuning, optimization of data transfer via specific binary protocols etc... so C# internals not come to an help (even if i think that knowing it may be really precious).

If you are facing applications with numerical analysis and/or greedy algorithm you could give a look at stackalloc/unsafe programming. This links is a good start:

http://content.atalasoft.com/h/i/58208059-improving-performa...

Hope this helps :)

by anonymous   2017-11-13
This one: https://www.amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454?
by anonymous   2017-08-20

While the exact details of the type system are implementation dependent, let me go into some more detail than just stating that it depends and you should not care. I'll describe how it approximately works in Microsoft's implementation (.NET) according to the book CLR via C# by Jeffrey Richter and the article See How the CLR Creates Runtime Objects by Hanu Kommalapati et al. (original MSDN May 2005 issue).


Say you have a class:

class Foo
{
    // Instance fields
    string myBar = "Foobar";
    int myNum;

    // Static fields
    static string bar = "Foobar";
    static int num;
}

Foo myFoo = new Foo();
Type typeOfFoo = typeof(Foo);

Where do the instance fields live?

Whenever you say new Foo(), space is allocated and initialized for the object instance, and the constructor is called. This instance is shown as instance of Foo in the image below. Such as instance contains only the instance fields of the class (in this case myBar and myNum), and for objects allocated on the heap two extra fields used by the runtime (Sync block index and Type handle). The type handle is a pointer to a Type object that describes the type of the instance, in this case type of Foo.

When you say new Foo() again, new space is allocated which will again contain space for the instance fields of the type. As you can see, instance fields are associated with object instances.

The runtime puts each instance field at a fixed offset from the start of the object's data. For example, myBar might live at offset +4. The address of the instance field is simply the address of the object plus the offset of the field.

Where do the static fields live?

Static fields in C# and Java are not associated with any object instance, but with a type. Classes, structs and enums are examples of types. Only once (per type) is some space allocated to hold the values of the static fields. It would make sense to allocate space for the static fields in the Type structure that describes the type, since there is also only one Type object per type. This is the approach taken by C# and Java.

The Type object1 is created when the type is loaded by the runtime. This structure contains all sorts of information needed for the runtime to be able to allocate new instances, call methods and perform casting, among other things. It also contains the space for the static fields, in this case bar and num.

The runtime has put each static field at some offset from the start of the type's data. This is different for each type. For example, bar might live at offset +64. The address of the static field is the address of the Type object plus the offset of the field. The type is statically known.

Displays some object structures, and their relationships.

1) In Microsoft .NET multiple different structures describe a type, such as the MethodTable and the EEClass structures.

by anonymous   2017-08-20

I'd say, probably not. Although this question is a bit rhetorical, take a look at this article/book excerpt, by Jeffrey Richter, Stop the madness (from the book CLR via C#). It discusses just those things you ask.

If all we cared about was raw performance, then the optimum number of threads to have on any machine is identical to the number of CPUs on that machine. [...] All threads still have a kernel object, kernel-mode stack, and other resources allocated to them. This trend of creating threads willy-nilly because they are cheap has to stop; threads are not cheap—rather, they are expensive, so use them wisely.

I highly recommend that book. Well worth reading front to back, although it is fairly big, ~900 pages.

Multi-threading though is a very complex subject and cannot be easily answered in just a few lines, it is highly dependent on what you are trying to achieve. As always, it depends and you have to measure/evaluate/optimize any solution to get optimal performance. However, just routinely dishing out threads is probably not a good idea in general. As a side note, a managed thread allocates 1 MB stack memory, meaning that creating (and holding on to) threads in a .NET application can be very wasteful.

Also, just because a tread exists does not mean that it is consuming a full core. It may do some work, but it may also sit idle and wait for some work to come along (which is the most likely case, otherwise your overall CPU consumption would constantly be closer to 100 than 0). They do however consume, or more correct, waste system resources.

Introducing threads adds a significant amount of extra complexity to your application, even though many techniques are being introduced to make them easier to use (various parallel frameworks etc.). The underlying complexity is still there though, sometimes posing as harmless, but always ready to burst out into its true nature (timing issues, deadlocks, debugging complexity etc).

In short you might say, "Do not use multiple thread unless you have a reason to".
Even then, t(h)read lightly.

by anonymous   2017-08-20

Ahh, I finally figured it out. I found the following comment buried in ch. 27 of Jeffrey Richter's CLR via C#:

When a Timer object is garbage collected, its finalization code tells the thread pool to cancel the timer so that it no longer goes off. So when using a Timer object, make sure that a variable is keeping the Timer object alive or else your callback method will stop getting called.

My timer was getting gobbled up by the GC! I created a private variable in my AppointmentsControl class and that solved the problem.


What puzzles me is that the official documentation specifically prescribes the approach that I originally used. It's too bad that page doesn't allow user feedback.