Calling Conventions Between (Un)Managed Code

I have just finished writing a virtual driver for Citrix. Along the way I had some major roadblocks which included not being able to get the VCSDK samples to work. That took me a solid 8 hours but after that it was more or less smooth sailing. Until I hit the calling convention issue:

As it stood, I already had built an RDP plugin for MSTSC and wanted to leverage what code I already had. This was purely coded in C# and worked fine. The ICA version of the plugin however was to be coded in C++ and so I had a situation where I was to call .NET exported methods from an unmanaged library. With a managed language, you can use the DllImportAttribute to PInvoke your native function calls. The CLR does a good job of matching everything up and with marshaling you are good to go (not to mention you can get a lot of help from pinvoke.net)! I had never gone backwards though, prior to this.

To import my managed methods into my unmanaged ICA plugin library, I had to use LoadLibrary() and GetProcAddress(). This was actually pretty simple as well until I hit the error shown above. I came to find out that all of the VCSDK is written in C using __cdecl. However, .NET uses __stdcall as its calling convention. So when you call a __stdcall function from a __cdecl function you get the above issue.

To my knowledge, there is no way to change .NET’s calling convention from within the IDE (Visual Studio) so you have to resort to modifying the IL. If you were to disassemble (ILDASM) your compiled library you would notice something along the lines of:

.method public hidebysig static void
modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall)
DataArrival(native int umbytes, uint16 len) cil managed

All that needs to change is the CallConvStdcall to CallConvCdecl. You can of course do this manually but there is another way. If you were to create an attribute class and then just decorate your methods with that attribute, you could scan through your IL searching for these attributes. If you were to then write an application to disassemble, find all of the custom attributes, and then modify the conventions before re-assembling the final piece you automate the system ;)

Always seeming to be a day late

Job hunting is never fun. Anxiety, pressure, waiting… For me it is a rather stressful process and even though the rewards are well worth the adventure, the trials leading up to them are quite intense. One thing I have noticed in the years I have been job hunting in the development sector is that I always seem to be off the ball.

This does not stop me from acquiring new work, simply that it hinders my acquisition of said new work. I try to stay on top of the new technologies, but when you spend all day working as a developer, you rarely want to go home and program some more. So as you work for a company you begin to settle into their technologies and let the ones blooming all about you wilt and fade.

When the time comes for a new job, I find that the techs I was using at my former job no longer apply to what is being sought and once again I am behind the curve. Looking about today, it seems that everyone wants C# .NET development, but they do not want desktop developers, nor do they want back-end developers. Instead what they seek is ASP.NET MVC developers. In the .NET space, this is probably my greatest weakness.

When trying to learn a new technology, simply reading about it is not enough, it just doesn’t stick for me. So I need to come up with some kind of goal to strive toward that will let me leverage the new technology. I have a friend that sells online as ararities through e-bay and craigslist, all kinds of items (far too many categories to list here). However, he would like to move more into his own space rather than feeding off these other two aforementioned spaces. This has become the perfect goal for me to explore ASP.NET.

With this new goal established, my next set of blogs will follow my progression through learning ASP.NET. Cool features discovered, traps succumbed to and any resources I happen to come across that help move me toward becoming a web developer in the .NET space!

Dynamic Runtime Lambda Expressions

Recently I needed to move from an old mySQL backend to a new MSSQL backend. In doing so, I decided to use LINQ to SQL. I am a huge fan of LINQ and wanted to use it as much as possible in the DAL (Data Access Layer). I really did not have much of an issue, until I ran across a situation where I needed a way to handle the SQL keyword ‘LIKE’. In SQL you can do something like:

SELECT * FROM dbo.MyTable WHERE name LIKE '%the%fox%'

This will pull back all matches that contains ‘the’ and ‘fox’. I wanted something similar to this in LINQ, but there did not seem to be anything built in. So I designed my own runtime generated lambda. I figured the closest string comparer to the ‘LIKE’ command was string.Contains(…). However, in the previous example I would need two contains. Since the number of the Contains() calls would be dynamic and based on how many ‘%’ symbols were found in the string, I could not use the LINQ shorthand. Instead I needed to dig a bit deeper and this lead me to the Expression class (and derivatives thereof).

PropertyInfo pInfo = typeof(CustomerAccount).GetProperty(“AccountId”, typeof(string));
ParameterExpression classExp = Expression.Parameter(typeof(CustomerAccount), “custacct”);
MemberExpression propExp = Expression.Property(classExp, pInfo);

MethodInfo containsInfo = typeof(string).GetMethod(“Contains”, new Type[] { typeof(string) });
Expression mc = Expression.Call(propExp, containsInfo, Expression.Constant(pieces[0].ToLower(), typeof(string)));
for (int i = 1; i < pieces.Length; i++)
{
    string piece = pieces[i].ToLower();
    ConstantExpression exp = Expression.Constant(piece, typeof(string));
    MethodCallExpression mcExp = Expression.Call(propExp, containsInfo, exp);
    mc = Expression.AndAlso(mc, mcExp);
}
Expression <Func<CustomerAccount,bool>> lambda = Expression.Lambda <Func<CustomerAccount, bool>>(mc, classExp);

In the previous code example, CustomerAccount is a class defined as follows (with AccountId being the property that will be ‘LIKE’d against):

class CustomerAccount
{
    public string AccountId { get; set; }

    public CustomerAccount()
    { AccountId = string.Empty; }
    public CustomerAccount(string acctId)
    { AccountId = acctId; }
}

The variable ‘pieces’, from above, is defined as:

string[] pieces = new string[]{ “the”, “fox” };  //Designed to mock '%the%fox%'

First thing we do is get the PropertyInfo of our CustomerAccount.AccountId property. This will allow LINQ to dynamically refer to it from behind the scenes. We then create a ParameterExpression. This will represent parameter(s) going into the final LINQ expression and is based on a given type (in this case, CustomerAccount). Next we create a MemberExpression that will represent the property of the ParameterExpression we just created. That is the foundation for the dynamic LINQ expression to be compiled at runtime.

Now we need to throw the string.Contains() method into the mix. First we use reflextion to get the MethodInfo of the Contains() method (standard Reflection here). We can assume that there will always at least be one ‘piece’ to check against the AccountId. We make this call by using the Expression.Call() method. This Call() method takes a MemberExpression (as the expression that will have the call made against it), a MethodInfo (of the method to call against the MemberExpression) and any parameter(s) to be passed into the method being called against the MemberExpression.

As of right now, ‘mc’ is roughly equivalent to: custacct.AccountId.Contains("the")

This of course is not a lambda expression, but merely an unevaluatable expression. A component of our final product. The for loop following, will pick up any additional ‘pieces’ and add them to the mix in the same fashion. The code of note in the for loop, is the call:

mc = Expression.AndAlso(mc, mcExp);

This statement will create an ‘&&’ portion to the expression. After our for loop (which iterates only once, for the “fox” portion of the ‘pieces’ array), ‘mc’ is now roughly equivalent to: custacct.AccountId.Contains("the") && custacct.AccountId.Contains("fox")

The last step in the process is to form the expression into an actual lambda expression by making a call to Expression.Lambda<>(). The two parameters to this method call are the Expression we have been creating (mc) and the ParameterExpression(s) that will be passed into the lambda. At this point, if you were to print out lambda.ToString(), you
would see the following output: custacct => (custacct.AccountId.Contains("the") && custacct.AccountId.Contains("fox"))

That is the exact, dynamic, lambda expression we are after, how do we use it though? lambda.Compile() returns Func, which can be passed into any method expecting a Func parameter. Essentially, anywhere you would have coded the above statement, can now be replaced with: lambda.Compile(). We now have dynamic, runtime lambdas!

Now this was a simple example and does not take into account certain aspects of the SQL LIKE statement, such as: order of tokens(%1%2%3%), startswith (1%2%) or endswith (%2%3). However, it was enough for my needs. Good luck on creating your own!

Multiple UI Threads and the ApplicationContext

When you create a windows forms application, you are given a default program.cs file that contains the following code:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

When this application is run, a single UI thread is created. A UI thread is one that contains its own message pump/loop. As such, it receives windows messages and dispatches them off to the active form/control. This is standard stuff and provides for a responsive UI.

Writing a program that has a potentially long loading time is a perfect target for a splash screen. Display the splash screen while loading the main application, then kill the splash screen and display the main window. This lets the user know that the program is loading, especially when there is status readout on the splash screen itself.

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    splash = new SplashForm();
    Thread t = new Thread(SplashThread);
    t.Start();
    Application.Run(new Form1());
}
public static SplashForm splash;
static void SplashThread()
{
    splash.Show();
    while(splash.IsShown) Thread.Sleep(100);
}

My first pass at implementing this resulted in a splash screen that did not update, even its initial drawing. A mere gray box was shown (where my splash screen should have been), until the main window was ready to be displayed. It made sense that that the splash screen would need to be run in its own thread so that it could update itself while my loading took place. Simply spinning up a thread for it, however, was not the answer. The problem with a common thread, it is only a processor time slice and does not contain a message pump by default.

A quick skim through MSDN led me to creating multiple UI threads. Essentially, calling Application.Run() from within a thread, turns that thread into a UI thread with its own message pump! So this time, my code changed to something like:

static void SplashThread()
{
    Application.Run(splash);
}

This not only kept the SplashThread from closing (avoiding the clunky IsShown property), but it also sent updates to the splash window. Problem solved! (Well not quite).

As it turns out, the default ApplicationContext (hidden from you) only expects a single UI thread. This thread is kept alive until the form that was passed into Application.Run() is closed (or Application.Exit() is called in the case where no form is passed into Application.Run()). When two UI threads are spun up, killing either, signals to the CLR that your application has finished. This signal is passed on to windows which reactivates the last window before your application was launched. However, since your application still has a thread running, the application itself does not die until both UI threads are killed. Let’s look at the scenario from above:

  1. The program is launched from Windows Explorer
  2. The SplashThread spins up and calls Application.Run(splash) [This thread is now a UI thread]
  3. The main thread calls Application.Run(new Form1()) [This thread is now UI thread #2]
  4. The splash screen finally gets destroyed and the CLR, seeing that the UI thread went down, signals to Windows that the program is no more
  5. Windows activates Windows Explorer, which brings it to the front, over your UI thread #2, the main application window
  6. You now have to manual set focus to the program that was launched, to bring it into focus

This is when I discovered the ApplicationContext class. This class informs the CLR when your program is finished. An instance of this can be passed into the Application.Run() method, and if you don’t, then one is created for you. If you were to look under the covers, you would see that passing a Form into Application.Run() causes an instance of ApplicationContext to be created behind the scenes. This instance plugs into your Form and watches for the FormClosed event. When it is signaled, the ApplicationContext.ExitThread() method is called which signals to the CLR that you are done. To get around this single form schema, I made my own derived version of ApplicationContext called SplashApplicationContext. The code for this guy looked something like this:

class SplashableApplicationContext : ApplicationContext
{
    #region Fields
    private int _formCount;
    private Splash _splashDlg;
    private MainView _mainDlg;
    #endregion

    #region Methods
    #region Constructors
    public SplashableApplicationContext()
    {
        _formCount = 0;

        Application.ApplicationExit += new EventHandler(Application_ApplicationExit);

        _splashDlg = new Splash();
        _splashDlg.FormClosed += new FormClosedEventHandler(OnFormClosed);
        _splashDlg.FormClosing += new FormClosingEventHandler(OnFormClosing);
        _formCount++;

        _splashDlg.Show();

        _mainDlg = new MainView(_splashDlg);
        _mainDlg.FormClosed += new FormClosedEventHandler(OnFormClosed);
        _mainDlg.FormClosing += new FormClosingEventHandler(OnFormClosing);
        _formCount++;

        _mainDlg.Show();
    }
    #endregion

    #region Event Handlers
    void OnFormClosing(object sender, CancelEventArgs e)
    {
        /* Do nothing for now */
    }

    void OnFormClosed(object sender, EventArgs e)
    {
        _formCount--;
        if (_formCount == 0)
            ExitThread();
    }

    void Application_ApplicationExit(object sender, EventArgs e)
    {
        /* Do nothing for now */
    }
    #endregion

    #endregion
}
 

The code is pretty self-explanatory, and can be modified to suit just about any needs. My finished program.cs code fragment looks like this now:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new SplashApplicationContext());
}

Unit Testing Attributes

When creating a unit test class, you’ll want to decorate a number of methods with Microsoft.VisualStudio.TestTools.UnitTesting attributes. These attributes are as follows:

  • TestClassAttribute
  • TestMethodAttribute
  • TestInitializeAttribute
  • TestCleanupAttribute
  • ClassInitializeAttribute
  • ClassCleanupAttribute

These attributes will roughly specify the order in which the methods (that they decorate) will be executed. That rough order is:

  1. ClassInitializeAttribute (CIA)
  2. TestInitializeAttribute (TIA)
  3. TestMethodAttribute (TMA)
  4. TestCleanupAttribute (TCA)
  5. [Repeat steps 2 - 4 until no more TestMethodAttributes found in TestClass]
  6. ClassCleanupAttribute (CCA)
  7. Next TestClassAttribute [until no more are found]

Note that the order of the TestMethods is not guaranteed unless you do an ordered test.
Where I ran into trouble is when I ran a test suite. The test suite contained about 5 different TestClassAttribute classes. Each class had its own ClassInitializeAttribute and ClassCleanupAttribute which I needed to run before the next Test Class was run. However, the testing engine only guarantees the order previously shown. It does not guarantee that all 6 steps will be completed before the next test class begins.

So if you have two test classes:
TestClassA (CIA, CCA, TIA, TCA, TMA1, TMA2, TMA3)
TestClassB (CIA, CCA, TIA, TCA, TMA1)

The testing engine could run the following and still maintain its rough ordering rule (above):

  1. TestClassA.CIA
  2. TestClassA.TIA
  3. TestClassA.TMA2
  4. TestClassA.TCA
  5. TestClassA.TIA
  6. TestClassA.TMA3
  7. TestClassA.TCA
  8. TestClassB.CIA
  9. TestClassB.TIA
  10. TestClassB.TMA1
  11. TestClassB.TCA
  12. TestClassA.TIA
  13. TestClassA.TMA1
  14. TestClassB.CCA
  15. TestClassA.TCA
  16. TestClassA.CCA

This has been reported to Microsoft and their response was that this is as designed. If you need your tests to run in a specific order then you should wrap the tests in an ordered test.

Unit Testing with External Resource Dependencies

Visual Studio 2010 has a nicely integrated testing environment. You can create a Test Project (add it to your solution) and then begin setting up unit tests and such as you go. You can do TFD or TDD from within VS without needing any 3rd party tools (though some tools may make it even easier). I am working on changing my train of thought over to TFD (Test First Development) as opposed to TDD (Test Driven Development). Until then, I still write some blocks of code, then follow up with a quick unit test to validate. These random tests I do while programming break the methodology of TFD but they provide me clues that I am on the right track in my coding. The types of tests I am talking about are probably more similar to integration tests in that I am testing against external resource dependencies (ERD).

What I mean by ERD is something like a text file that contains data that is to be read into the application at runtime. If you have run unit tests from within VS you might find that simply telling a resource to “Copy Always” to the output directory does not make that resource available to the test run.

Properties dialog for external dependency


This is because of the way that VS runs the tests.

When you run unit tests from within VS, the IDE creates a temporary directory in the <project directory>\TestResults directory that is titled the same as your test result file. In this temporary directory exists an \IN directory and an \OUT directory. The \OUT directory is where your tests are run from. After the compiler finishes with your code, it copies all PE, .config, resources, etc. to your output directory as normal. Then VS, copies the required files from your output directory to the \OUT directory, mentioned above, just before executing the test code. If your tests depend on external resources, such as text files, images, etc. You can add these to the \OUT directory by placing an entry in local.testsettings file (located in the solution Items folder in your VS solution).

Solution explorer dialog

  • Click the Deployment list item
  • Enable deployment
  • Add files\directories that are required.

Local test settings dialog

Now when your test is run (from within VS), these files/directories will be placed there first, before the code is executed. This temporary test directory [<project directory>\Test Results\<test result file>\], is normally deleted after the test has run (unless your test fails).

VS2010 Caches The Registry?

I’m not quite sure how or why it happened, but it seemed that VS2010 was caching my HKLM registry. I was writing an application that handles a node in the registry.

HKLM\SOFTWARE\Wow6432Node\MyCompany\MyApp

There are 3 values under this node:
regval1 (DWORD)
regval2 (String)
regval3 (String)

The ‘regval1’ value does not exist at first. Instead, when the user is ready, they add it (through the application). Should this value need to be removed, the user can delete it from the registry as well (through the application). Here was my code:

public bool AddMyValueToRegistry(int val)
{
    string keyName = @“SOFTWARE\MyCompany\MyApp”;

    try
    {
        using(RegistryKey rKey = Registry.LocalMachine.OpenSubKey(keyName, true))
        {
            if(rKey == null)return false;

            string valName = “regval1”;

            rKey.SetValue(valName, val, RegistryKind.Dword);
            return true;
        }
    }
    catch(SecurityException sex) { /*Handle Exception*/}

    return false;
}


public bool RemoveMyValueFromRegistry()
{
	string keyName = @“SOFTWARE\MyCompany\MyApp”;

	try
	{
		using(RegistryKey rKey = Registry.LocalMachine.OpenSubKey(keyName, true))
		{
			if(rKey == null)return false;

			string valName = “regval1”;

			try
			{
				rKey.DeleteValue(valName, true);
				return true;
			}
			catch(ArgumentExcecption){/*Handle Exception*/}
		}
	}
	catch(SecurityException sex) { /*Handle Exception*/}

	return false;
}

After implementing the code and testing a few times, I ran across a unique issue, which I since, cannot reproduce. After I called the AddMyValueToRegistry(4) method, I broke into the code and checked that there were 3 values under my [..\MyApp] node. Looking in regedit.exe to verify, this proved to be true. When I then called the RemoveMyValueFromRegistry() method, I was informed by the CLR that ‘regval1’ did not exist. Looking back at regedit.exe, I see that my value does indeed exist. When I broke into the running code to examine my rKey object, calling rKey.GetValues() (from the watch window) showed that there were indeed 3 values, however, rKey.DeleteValue(…) still failed. I then restarted the application after deleting the ‘regval1’ manually with regedit. Checking my rKey.GetValues() still showed that there were 3 values under the [..\MyApp] node!

At first I thought this was due to the fact that I was running a 32-bit application in a 64-bit OS. The Wow6432Node had given me trouble in the past. However, there existed no [HKLM\SOFTWARE\MyCompany] node, so it had to be referring to the Wow6432Node. To test this even further, suspecting that the vshost.exe had something to do with it, I ran the application outside of VS. Sure enough, that version worked perfectly. I rebooted VS and then reloaded the project. Upon testing the application from within VS, the issue was no longer there. The question is, did VS cache my registry, and if so, why?

Another Reason to Do it Right the First Time

If you were to ask me if I thought of myself as being a creative person, I would respond with an affirmative “No”. When in fact I know that I am. You really have to be in order to be a developer. There will be very few situations (if any) in your programming career where specifications will be given to you that read like the instructions that come with a lego kit. In fact, if they did, what programmer would really want the job? We need to be able to express ourselves through our code, otherwise what fun is it to code?

The reason I steadily answer no is because when I try to be creative, I lock up and fail miserably. Think of it as you would writers block. It applies to any topic that puts me on the spot to be creative (and is probably due to some inner anxiety that I have). When I don’t try to be creative I usually overdo it. For example if you were to give me a problem that needed to be coded I would undoubtedly come up with a very creative solution at first, but it would probably not be the simplest (or most efficient) solution. When trying to think up names for solutions, projects, collections, etc., it is inherently apparent at how uncreative I truly am! In code however, we have refactoring and can go back later to change it up as we see fit.

When dealing with small projects this is all very trivial as it does not usually take much effort to change things around. When you get into distributed programming, this is not so. One minor change in your solution can affect many other projects, even those that do not pertain to the solution in which you made the change. Many different coding paradigms aim to fight this tight coupling of code and I subscribe to as many as possible (IoC, DI, etc.). Legacy code is the real killer. If you have an entire distributed system of legacy code it will more than likely be tightly coupled. Legacy systems are usually far too large to rewrite completely and are generally broken into components and rewritten in pieces (if at all). As new projects get added into the system, you want them to be loosely coupled, yet they have to work with the tightly coupled system. This demands creativity! All in all, it is not as hard as it is frustrating. At least it is modifiable and not set in stone.

So if we are starting a new project, we need to look ahead far enough to realize that what we code today, is going to be rewritten tomorrow. Whether it is a simple refactoring or a complete rewrite, nothing is permanent, least of all our code. Being that, I am very comfortable with change. I become disgruntled when I see developer tools that do not embrace this theory. Especially when they come from Microsoft…

If you are familiar with TFS 2010, you will know that there is a hierarchical structure to their team setups. You have:

A Team Collection (which holds all of the collection’s team projects)
A Team Project (which holds all of the team project’s solutions)
A Solution (which holds all of the solution’s projects)
A Project (which holds all of the project’s source code)

If you do not develop with TFS, then you should at least be familiar with solutions and solution projects (assuming you subscribe to Visual Studio). When you create a new project, you are prompted to add the project to a new/existing solution.

– Scenario –
So you create your project, “MyToolConfigUtility” and add it to your new solution, “MyToolSolution”. “MyTool” is a product that is part of a distributed legacy system. The legacy system has 3 other main products and they each have their own configuration utilities. So you get in there and hammer away at code and in a while have a working application to configure your “MyTool” application.

Since we are using TFS, we have also created a team collection called “MyCompaniesMainLineCollection” (for which will contain all of the projects that are part of the main line of software sold to the end user). Within this collection we have also created a “MyToolTeamProject” (which will contain any solutions that are inherent to the “MyTool” product). Personally, when I create my team projects, I tend to keep them to a single solution and just add projects to the solution for each different facet of the team project.

Our hierarchy looks like this thus far:

(team collection) tfsserver\MyCompaniesMainLineCollection
(team project) MyToolTeamProject
(solution) MyToolSolution
(project) MyToolConfigUtility

After a few months, it comes to the attention of the designers/architects that a lot of the configuration utilities (4 of them currently exist) share the same algorithms and procedures. However, 1 of them is written in VFP, 2 of them are written in unmanaged c++ and yours (MyToolConfigUtility) is written in c#. It has been decided that they all need to be combined into one c# implementation. This shouldn’t be too hard since they all basically do the same thing and you have most of the code already written in your MyToolConfigUtility project. However, the recoding is not the issue. The naming scheme is. This MyToolConfigUtility is no longer that, now it should be named the “MyCompanyConfigUtility”. So we want our hierarchy to look as follows:

(team collection) tfsserver\MyCompaniesMainLineCollection
(team project) UtilityTeamProject
(solution) ConfigUtilitySoluction
(project) MyCompanyConfigUtility

With the above changes, we can simply add what was missing from the MyToolCOnfigUtility and whamo, we are good to go. Anyone that inherits our codebase later on should understand what this team project is just by looking at the previous hierarchy. The above however, is impossible. In TFS, you cannot rename a team project…WHAT?! :: sigh ::

At this point I find myself faced with two options. Either I change what I can, and leave the rest as it is:

(team collection) tfsserver\MyCompaniesMainLineCollection
(team project) MyToolTeamProject
(solution) ConfigUtilitySoluction
(project) MyCompanyConfigUtility

(which now makes no sense at all) or I start a new team project and copy over the solution into it. Moving the source code is not that difficult, but everything has to be done manually and if you are using the built in SharePoint portals, then may God have mercy on your soul (as they add an entirely other level of cluster fuck). Personally, I have chosen to start a new team project. Luckily for me, one of the companies I work with where this situation occurred does not yet use the SharePoint portals so the move should only take a little while.

– Avoiding the Disaster –
Having a set of specifications and a roadmap will help to alleviate these incidents. In the previous example, all of the company projects were created by different teams that worked in different environments, using different languages and only communicated when absolutely necessary. The good news is that a company that communicates regularly amongst their development teams and keeps an up-to-date roadmap (Agile?) will tend to avoid these situations all together. The bad news is, that from what I’ve read, seen and personally experienced, companies do not communicate well (in general), follow roadmaps or keep up-to-date specifications of their disparate systems. I am disappointed that Microsoft has not enabled us to rename our projects, but the underlying issue is that if you are ready for the issues when they eventually turn up (and they will) then you will not be caused such a headache!

Do it right, the first time! hehe.

Toying with System.Windows.Forms.BindingSource

Been having some trouble with a bindingsource lately. The situation was as follows:
I have a DataGridView (dgv1) control on my Form (frm1). The dgv1.DataSource is set to my BindingSource (bs1). I have a wrapper class (wrap1) that is used to wrap a list of my DTOs (a class named dto). wrap1 has a property named InnerList that returns List . In frm1.Load(), I load up the wrap1.InnerList property with a number of dto objects. I then assign bs1.DataSource to wrap1 and set bs1.DataMember to “InnerList”.

This displays all of my DTO data in the dgv1. Perfect!

private void frm1_Load(object sender, EventArgs e)
{
    this.wrap1 = new wrapper();
    this.wrap1.InnerList.Add(new dto()
        { Number = 1, Boolean = true, Word = “Hello” });
    this.wrap1.InnerList.Add(new dto()
        { Number = 2, Boolean = true, Word = “World” });
    this.wrap1.InnerList.Add(new dto()
        { Number = 3, Boolean = false, Word = “!” });

    dgv1.DataSource = bs1;

    bs1.DataSource = this.wrap1;
    bs1.DataMember = “InnerList”;
}

I now change my wrap1.InnerList by adding a few more dto objects to it. I then set bs1.DataSource to this new version of wrap1. And dgv1 displays all my new values! Perf….wait what?! Nothing has changed…

private void bt1_Click(object sender, EventArgs e)
{
    this.wrap1.InnerList.Add(new dto()
        { Number = 4, Boolean = true, Word = “Updated” });
    this.wrap1.InnerList.Add(new dto()
        { Number = 5, Boolean = false, Word = “\”InnerList\”" });

bs1.DataSource = this.wrap1;
}

As it turns out, I overlooked something so simple it is frustrating. When I set bs1.DataSource to wrap1, I was really giving bs1.DataSource a reference and not a copy of the wrap1 object. The BindingSource class contains an inner list (IBindingList) of its own named List. When you set a value to BindingSource.DataSource, it converts this value to an IBindingList and sets it to its own List property. When the databound control needs to sync with the BindingSource, the BindingSource returns its List property, not its DataSource property. So even though I give wrap1 new values, the bs1 object still thinks it is in sync, since the references have not changed. Setting bs1.DataSource to the “new” version of wrap1 effectively does nothing since bs1 ALREADY has this same reference set. Nothing is updated.

To resolve this, I have two options. I can set bs1.DataSource to null before I give it the newly constructed wrap1 object. This will force the BindingSource to sync its inner List property with the newly set DataSource. I also have to be sure and reset the bs1.DataMember back to “InnerList”. The other way I can do this is by calling the BindingSource.ResetBindings(bool) method. This method tells the inner bs1.List property to re-sync itself with the bs1.DataSource. Personally, I use the ResetBindings() method as it feels much less “brute force”.

Overlooking the Simple Things

The other day I decided it was time for blog entry. I typed it up and decided to drop it into WordPress. However, I couldn’t connect to my site. I could still get into my home network, just not the server. On my home network I could still ping the server, but any attempt to ssh in led to “Network error: Connection refused”. My only option was to interact with the physical box so after about 20 minutes of (un)hooking everything up to the server I gave it a reboot and the screen was locked with the following displayed (and no prompt):

/dev/sda1: clean, 148755/15024128 files, 5527300/60082688 blocks
modprobe: FATAL: Error inserting padlock_sha (/lib/modules/2.6.32-21-generic-pae/kernel/drivers/crypto/padlock_sha.ko): No such device

This was very discouraging. A quick google search and it turns out ([SOLVED] Suddenly FATAL error upon boot (Urgent!)) I have to black list the module as it is currently bugged.

“It’s just taking time to boot because the disk didnt unmount cleanly when you last shutdown, so the boot decides to run a fsck disk check for you. It doesnt display any text while it does this, but give it some time and it finishes the disk check.”

After waiting an entire day, I decided there had to be something else wrong. I stumbled across another article (10.04 server won’t boot, modprobe FATAL error). The user here had said to hold ESC or SHIFT while the machine was rebooting to get into the grub menu. Without even thinking I pressed the escape key (forgetting to reboot) and there was a response (a “screen saver” showing my version of Ubuntu and a “loading” elipses). So I tried ENTER and bam! The server finished booting up and everything was back to normal.

Well I still had to make the change to fstab.

/dev/sdb1 /mnt/external auto defaults,user/noauto 0 0

That was the line that automounted my external drive and since the drive was no longer connected to the machine, on boot, it would fail. Commented out (prefixing the line with a hash ‘#’ symbol), my server was back up and running! So the moral of the blog is don’t overlook the simple things. If I had just tried banging on the keyboard, I would not have been down for 3 days.

Return top