Posts Tagged ‘.NET’

How much complete a framework can be : MS vs. Apple

As a person who major in CS, I have interest in fundamental technology or techniques like compilers, OS, 3D graphics, computer vision, parallel systems & distributed systems. So, one of the reason I started to work with 3 major OSes, i.e. Windows, Unix and Mac, and have had lots of interest in their architectural design. Therefore I like to work with different frameworks and compare their design or philosophy behind them.

I think OS architecture is like a whole picture, while frameworks are each part of the OSes. What architectural design an OS has is reflected to its frameworks. When overall architecture design affect how they work, how their components are related one another and so on, frameworks for them should be designed as such. This is one of the reason I think Apple should have filed with OS architectures than their visual UI design against MS and Google.

Here, I would like to show the very difference between .NET and Cocoa. If you have followed ToolBox API and Win32/MFC, you will see similarity between Apple’s and MS’s. Also, there are similarity between Cocoa and .NET. I think it is because Objective-C/Cocoa is in the SmallTalk camp which test OOP concept in academia and geared toward SE, while C++ is in Simula camp which is more for real industry field. Because C++ is for more real field, it should have been compromised with many restriction like CPU speed etc. Also the C++ has been evolved for everything for all people. So, although C++ was introduced as THE OOP language, it has many different concept like meta programming, ad-hoc polymorphism. Also, because of that it also contains its syntax which became somewhat bad and some concept got to have many semantics. (e.g. extern vs. static ) C# is not too different from C++ in that. Although MS streamlined C# from C++. (actually C# was influenced more by Java at first. But as its name suggests it has the face of C++. # in its name is somewhat amusing. When they call it, don’t forget that it is called “sharp” rather than “pound”. # in musical notation is half higher than a note it is attached too. So, C# is C++ in that sense. ) I can feel those philosophy to be all for all from C#.
However, Objective-C and Cocoa was evolved to be focused to increase productivity. So, when using Objective-C and Cocoa, you naturally become to focus on core logic rather than “how to achieve that”. Objective-C is more simple and Cocoa is designed to be very intuitive and powerful.

OK. Let’s see how Objective-C/Cocoa achieves “GUI code on main thread”.

- (IBAction)doInThread:(id)sender
{
    [NSThread detachNewThreadSelector:@selector(doSomethingMethod:)
                             toTarget:self withObject:nil];
}

// Thread method
- (void)doSomethingMethod:(id)object
{
    // Calls appendLogMessage: on main thread
    [self performSelector:@selector(appendLogMessage:)
                 onThread:[NSThread mainThread]
               withObject:@"Do something..."
            waitUntilDone:YES];
}

- (void)appendLogMessage:(NSString *)messageString
{
    NSTextStorage *textStorage = [m_logBoxView textStorage];
    NSUInteger theLastPos = [textStorage length];

    [m_logBoxView setSelectedRange:NSMakeRange( theLastPos, 0 )];

    [m_logBoxView insertText:[NSString stringWithFormat:@"%@\n",
                              messageString]];
}

It’s very intuitive. (Don’t confuse with that you don’t understand Obj-C code. Once you get used to it, it is very easy and straightforward. ) The appendLogMessage: is written just like a normal message/method.

Now, let’s check how it looks in C#/.NET.

#region MSDN way
private void m_doSomethingButton_Click(object sender,EventArgs e)
{
    m_choreThread = new Thread(new ThreadStart(this.StartThreadLoop));

    m_choreThread.Name = "MSDN Thread";
    m_choreThread.Start();
}

// Thread method
private void StartThreadLoop()
{
    // This is a thread loop
    int i = 0;

    while (i < 10)
    {
        // 1. Call WriteLogMessage()
        this.WriteLogMessage(String.Format("Do chores hard!!! {0} from {1}", i, m_choreThread.Name));

        i++;
    }

}

// 2. Visit this in the non-main thread space
// 5. Visit this in the main thread space
private void WriteLogMessage(string msgString)
{
    // 3. If it is still in the context of a non-main thread
    if (m_logTextBox.InvokeRequired)
    {
        WriteLogMessageCallback writeLogMessageDelegate = new WriteLogMessageCallback(WriteLogMessage);

        // 4. Invoke in its main thread space
        this.Invoke(writeLogMessageDelegate, new object[] { msgString });
    }
    else
    {
        // 6. Call this in the main thread space.
        m_logTextBox.AppendText(msgString + Environment.NewLine);
    }
}
#endregion

I commented how things are visited in the C#/.NET case to help your understanding. So, to you, who use the framework, .NET case prevent you from concentrating on the main logic. In other words, you should know how things work in C#/.NET.

One of the virtue of OOP is data hiding and encapsulation. Although it says “Data Hiding”, it’s not only about “Data” but also “how it works internally.” C#/.NET fails in this area seriously as you can see. In other words, you should be aware of in which thread context the WriteLogMessage() is called and the method should be implemented with that knowledge.
Compared to that, messages in Objective-C/Cocoa can be written just like usual messages.

Then, are they really different? Couldn’t MS make their .NET framework as elegant as Cocoa? No. I don’t think so. It looks to me that Cocoa’s underlying code could be similar to that of .NET. The difference is that how much Apple people refined their framework by considering people who actually use their framework and design the framework to let people to focus on their own logic not on how Apple implemented this and that.

Then, let’s try to make it look similar to that of Objective-C/Cocoa.

#region Cocoa Way
private void m_doSomethinginCocoaWayButton_Click(object sender, EventArgs e)
{
    WriteLogMessage2(Environment.NewLine + "----------------------------" + Environment.NewLine);
    m_choreThread = new Thread(new ThreadStart(this.StartThreadLoop2));
    m_choreThread.Name = "Cocoa Thread";
    m_choreThread.Start();
}

private void StartThreadLoop2()
{
    // This is a thread loop
    int i = 0;

    WriteLogMessageCallback writeLogMessageDelegate = new WriteLogMessageCallback(WriteLogMessage2);

    while (i < 10)
    {
        this.performOnMainThread(writeLogMessageDelegate,
                                 new object[] { String.Format("Do chores hard!!! {0} from {1}", i, m_choreThread.Name) } );

        i++;
    }

}

private void performOnMainThread( WriteLogMessageCallback methodToInvoke, object[] parameter )
{
    if (m_logTextBox.InvokeRequired)
    {
        this.Invoke(methodToInvoke, parameter);
    }
}

private void WriteLogMessage2(string msgString)
{
    m_logTextBox.AppendText(msgString + Environment.NewLine);

}
#endregion

Don’t bother with the method name “performOnMainThread“. It’s not our interest. Whatever the name is, it doesn’t matter. What we need to focus on here is the pattern of how WriteLogMessage2() is called.
Also, additionally assume that Object class in .NET framework, which all classes are inherited from, contains the performOnMainThread(). Then like Cocoa, you can ask an object to invoke a given method on main thread. Then you, as a application program developer, can write the method to be invoked without worrying about knowing how those invoke system works.

Similar things happens with timer invocation. If you want to invoke a message at certain intervals in Cocoa, the code is very straightforward and very clean. However, in Win32/MFC case, the OnTimer() handler should check what timer triggers this timer event. In this case, it looks to me that Apple people utilizes signals and events. (Signal is so-called H/W events while event is called S/W event, if you want to be specific about the terms. ) I will not show sample code for that here.

Point here is that the level of refinement is higher on Apple’s. Cocoa framework is designed for SE more in mind, while MFC/.NET are more about “Let’s put this on the market as quickly as possible.” Good news is that.NET is more similar to Cocoa than their previous frameworks, because NeXT showed a future a while ago and MS looked to adopted that.

I always wonder why MS simply adopted Objective-C/Cocoa for their platform development. Well, C#.NET was a kind of a gun toward Java and MS languages can share the same .NET framework. So, there is slight difference, but even with Objective-C/Cocoa, there is a language bind. Well.. it’s true that people should make their own Cocoa equivalent.. yeah.. that can be the major issue to MS.
( Well.. I know that not choosing Obj-C/Cocoa or OpenStep by MS was also due to market situation, marketing, etc, but here I would like to focus on technical side. )

I wonder how F-Script people and Ruby Cocoa people bridged their language to Cocoa. (Script Bridging tech.. )

How not to build with “ClickOnce” deployment option?

“ClickOnce” deployment is cleaner and easier option than “InstallShield” option. Also, it is free.
However, there is one glitch. ( MS people will call it a “feature”. )
“ClickOnce” doesn’t allow execution level higher than “AsInvoker”. So, it means that you can’t include a call to some functionality which requires “Administrator” privilege.
What? Isn’t it totally different thing to elevate execution level when launching, and building/deploying an executable? Right. However, it’s the approach MS people chose, and when building a project, it will warn and stop building.
In my code ( I got rid of “s” here, because my native English speakers said it was wrong if you wrote/speak codes. Well, a language keeps changing. According to English grammar book, you should not say, “Give me (a) milk”. A correct one will be “Give me a cup of blah blah”. But one very surprising thing I found in living here is that there has been virtually no person who ordered like “give me one cup of Cafe Mocha”, “Give me one glass of Coke” etc. They always say “Two Cokes”, etc ) I call WMI method to enable/disable network interface. It requires “Administrator” privilege.

So, I had to change a deployment method not to use ClickOnce.

However, how not to use ClickOnce? Isn’t it enough not to click “Publish” menu item?
Visual Studio still spit out the error message.

How to solve it is to turn off “Security Option” like shown below.

How to turn-off checking “ClickOnce” in building

 

The following is when the option is on.

ClickOnce doesn’t support “Administrator” level

 

 

Enabling and Disabling Network Interface on Windows using C#

It doesn’t need to be C#. The main thing here are :

  • WMI (Windows Management Interface)
  • Administrator Privilege

Once you get a reference to the WMI object, you can invoke its Enable() and Disable() method.

Let’s make things short. Here is example code.

static void DisableAndEnableNetworkAdapter(string nicName)
{
	ManagementClass managementClass = new ManagementClass("Win32_NetworkAdapter");
	ManagementObjectCollection mgmtObjectColl = managementClass.GetInstances();

	ManagementObject myObject = null;

	foreach (ManagementObject mgmtObject in mgmtObjectColl)
	{
		if (mgmtObject["NetConnectionID"] != null && mgmtObject["NetConnectionID"].Equals(nicName))
		{
			Console.WriteLine("found");
			myObject = mgmtObject;

			//object result = mgmtObject.InvokeMethod("Disable", new object[] {});
			//
			// When there is no parameter, you don't need to pass an object array with
			// no element in it.
			object result = mgmtObject.InvokeMethod("Disable", null);
			Console.WriteLine("{0}", Convert.ToInt16(result));
		}
		//Console.WriteLine("{0}, {1}", mgmtObject["Name"], mgmtObject["NetConnectionID"]);

	}

	object result3 = myObject.InvokeMethod("Enable", null);

}

(This code is written to be invoked from Main() method. So, it is declared as “static”. )
However, if you invoke this one in a Main() method, it will not change the activated status of a network interface. The reason is the executable doesn’t have “admin” privilege.

So, try to create you own app.manifest file and change the privilege like this.

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

If you want to know more about “requestedExecutionLevel”, please cf. Step 6: Create and Embed an Application Manifest (UAC)

If you want to do experiment with netsh, cf. How to disable Local Area Connection using Command Prompt in Windows 7?

In Channel 9 page of MS, it is said that they hosted “ToggleNic” sample project for this, but it is not possible to find it there. However, I found it somewhere else. The ToggleNic code contains one interesting thing. For “Disable”, the author passed new object[] {} as its 2nd parameter. However, for “Enable”, he just passed null. I was curious if passing an object array with nothing makes things different, but it didn’t. Why it was possible to enable/disable with ToggleNic was that it has its own app.manifest which is to obtain admin privilege. So, after I endow the same privilege to my project, it started to be able to enable and disable NIC including WIFI interface.

How to keep the reference to a delegate registered to a native API function

When you call a Win32 native function from C# using P/Invoke, there are times when the Win32 function requires a callback for various purpose like callback for status feedback.

Then, the callback functions are expected to be called repeatedly until it is unregistered.
However, the garbage collector frees up the callback function. ( It’s a delegate. )

Then how to prevent it from being collected?

Here is a nice blog post about it.
beefycode : Delegates and Native API Callbacks – Answer

In short, it is to declare a member variable to the delegate to make the subordinating class keep the reference to it.

MS doesn’t have philosophy in designing their framework

I would like to show very simple example.

These GetHeight() methods are declared in Font ( .NET )

GetHeight() Returns the line spacing, in pixels, of this font.
GetHeight(Graphics) Returns the line spacing, in the current unit of a specified Graphics, of this font.
GetHeight(Single) Returns the height, in pixels, of this Font when drawn to a device with the specified vertical resolution.

Method names and variable names should speak for themselves except for very special case where they lack of any nomenclature.

However, look at that. They are all GetHeight. However, what they return are different.
The first two return line spacing, while the last one is the height of a chosen font.
Because it is “GetHeight” of Font class, it should be the height of a font. That is self-explanatory for the method. So, the first twos are named wrongly. They should be “GetLineSapce()”. Also, because Windows now supports DPI-independency, the “GetHeight(Single)” should return a value in DPI independent unit. Moreover they should provide functions to convert the DPI independent size to device specific size, and vice versa. (ADDED : There is a way to do that currently. However, .NET is higher-level framework than MFC. Current approach looks more for Win32/MFC than .NET )

This shows that they don’t think about “what framework should address”. You can say that they didn’t have enough time for handling DPI-independence, but then they should not say DPI-independency in Windows 7 yet, just like Apple does for its Mac OS X.
More fundamentally, again, the method names are wrong.

Same paradigm : .NET and Cocoa

When people say, “Windows copied Mac”, they talk only about how they look, or their GUI. However, from the early days of Mac and Windows, I have said, “It is not about GUI. The more and obvious proof that MS copied Apple’s is their API.”

Why did the first Windows have many function call style in pascal type rather than C native? Why similar API functions had almost identical list of parameters and orders? If they designed those APIs for themselves, most of those APIs would have MS’s own pattern although there are possibility that some of them can be similar.

Even nowadays, I noticed such thing. The .NET methods and their patterns are very similar to Cocoa.

One of the weakest part of the Cocoa is that thread methods/functions can’t change GUI widgets like moving knobs of a slider, updating progress indicator in its context. It should ask a main thread to do so by calling “performSelectorOnMainThread” or something like that. ( The name of the method is very clear about what it does and in what context it performs. )

With Win32/MFC, MS platform didn’t have this restriction. Sure, those widgets or controls should be protected with locks. However, you can access and update widgets/controls from a thread other than a main thread.
However, this is changed in .NET. Although it is still possible to do so in unmanaged context, but in managed context, you need to ask underlying system to call an access method for the caller’s sake.

Example is :

private void SetText(string text)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.

    if (this.textBox1.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(SetText);  // 1. This "SetText" is this method itself
        this.Invoke(d, new object[] { text });    // 2. "this" is a WinForm form that contains "textBox1"
    }
    else
    {
        this.textBox1.Text = text;
    }
}

Why did MS change their mechanism similar to that of Cocoa? ( which is restricted. )
Also, it is not as clear as that of Cocoa.
The SetText() above is called inside of a thread. So, when “invokeRequired” is reached, it is still called from a thread, and when its “Invoke” ( actually its form’s Invoke, not the thread’s ) rather than the textBox1’s Invoke is called, it visit the same SetText again ( that is why there is no parameter to set “on which object the Invoke() is called” ), but this time, it is called in main thread’s context. So, the “else” part is called.

This shows the difference of elegance between Apple style and MS style.
Apple people implement things thinking “how to use it”, “What design is better.”, while MS people just implement without or minimally thinking about those.

What is even worse is, “why don’t MS people enhance Apple’s weak implementation?”. Just like Columbus’ egg, when you think an original idea, it takes time and your energy to squeeze the idea from your brain. So, for the first implementer, what is more important is that they did it, not how well they did it. However, in the case of MS, they borrowed that idea. Then they should have more time to think about how to enhance it. But they didn’t.
Probably this way of changing UI widgets are better approach and more systematic approach, but at least, style-wise they could enhance it. But they are uglier than Apple’s.

So, if you write in Cocoa, it is just one shot call. That is, you create methods which interact with GUI widgets on main thread, and in other threads, call performSelectorOnMainThread to let the main thread to call the method to modify GUI widget.

On the other hand, In .NET, it is like to implement your own performSelectorOnMainThread and that is visited twice.
Here,developers writing in Cocoa can get relaxed thinking that their favorite framework is not worse than .NET and rejoice because its simpler architecture.

Objective-C/Cocoa programmers can now justify the somewhat restricted architecture of interaction between threads and GUI widgets. :)

Wrong explanation in MSDN on C# delegates

At MSDN site, they described about what can be set as delegate this way.

When a delegate is constructed to wrap an instance method, the delegate references both the instance and the method. A delegate has no knowledge of the instance type aside from the method it wraps, so a delegate can refer to any type of object as long as there is a method on that object that matches the delegate signature. When a delegate is constructed to wrap a static method, it only references the method. Consider the following declarations:

public class MethodClass
{
public void Method1(string message) { }
public void Method2(string message) { }
}

Along with the static DelegateMethod shown previously, we now have three methods that can be wrapped by a Del instance.

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;

Instead of assigned to obj in the last lines of the codes above, d1 and d2 are assigned to obj.Method1 and obj.Method2.
So, it is not that the delegate can refer to any type of objects as long as blah blah. It just refers to those specific methods.

Let’s be careful.

%d bloggers like this: