by mathias 6. February 2010 13:26

I am currently working on a project which extends an Excel VSTO add-in model I had developed a few months back. This is a joint project, and my add-in has to interact with a classic Excel worksheet model, which got me worried. The original model read data from Excel into a C# object, which handles the heavy-duty computation, and writes back results to a spreadsheet once it is done. The modified model has to proceed in 2 steps: perform a partial read of the inputs, compute some outputs, feed them into the worksheet model, read some results from that worksheet, resume computations and write out the final outputs.

The reason I was worried is that the spreadsheet I have to interact with is a bit slow, and I was concerned about a race condition type of problem. What if the add-in attempted to read data from the worksheet, before Excel had time to update the values in the worksheet?

In order to check whether there was a problem, I created a small test case. I first wrote a VBA function which was on purpose very slow:

Public Function SlowFunction(arg As String) As String

    WaitFor 10
    SlowFunction = arg

End Function

Public Function WaitFor(seconds As Integer)

    Dim startTime As Double
    startTime = timer
    
    Do While timer < startTime + seconds
    Loop

End Function
The SlowFunction simply takes a string as input, calls the WaitFor function, which stays busy for a few seconds, and returns the input string after 10 seconds have elapsed. 

This allowed me to artificially create an extremely inefficient worksheet: when the input cell A1 is modified, the output cell A2 is updated only 10 seconds later.

SlowWorkbook

More...

by mathias 3. February 2010 13:25

Activating a worksheet is a fairly common task in Office automation; however, in a VSTO project, if you call:

myWorksheet.Activate();

… building the project will give you the following warning:

Ambiguity between method 'Microsoft.Office.Interop.Excel._Worksheet.Activate()' and non-method 'Microsoft.Office.Interop.Excel.DocEvents_Event.Activate'. Using method group.

I don’t like to have warnings in my projects when I can avoid it, but I never got to look into it. After all, it was “just a warning”, so I let it go.

The answer came to me via the Carter & Lippert VSTO book (aka “The Brick”), which I finally started reading through, and highly recommend. The gist of it is that the Worksheet interface implements 2 interfaces, _Worksheet and DocEvents_Event. _Worksheet contains the properties and methods that correspond to the Worksheet, including the Activate() method, while DocEvents_Event owns the events, including Activate, and these two names collide.

To disambiguate the call, you just need to cast the Workbook to the appropriate interface, the one which owns the method you are interested in. In my case, I want to Activate the workbook, and therefore use the following code:

((Excel._Worksheet)myWorksheet).Activate();

And sure enough, the warning is gone.

by mathias 31. January 2010 08:04

I have grown a bit frustrated by the difficulty to gather information about local .Net development community events. Of all people, I am one of the best-positioned to hear about these events, because of my involvement with the San Francisco .Net user group, and yet, I routinely discover that I missed an event, because there is no clear place to go to get that information and I never heard about it.

So here we go – ladies and gentlemen, introducing NorCalWeekly.Net, your weekly serving of .Net events in north California! My goal will be to provide in one place, on a weekly basis, announcements for all upcoming .Net events in the area – so if you know of anything relevant taking place, please let me know! The design and features are somewhat minimalist for the moment, I’ll improve it over time.

by mathias 27. January 2010 18:26

Mark Needham recently published a series of posts around TDD, and one caught my attention. He is mocking a series of calls to a method SomeMethod() of a service IService, and doesn’t really care about the arguments, but:

For the sake of the test I only wanted 'service' to return a value of 'aValue' the first time it was called and then 'anotherValue' for any other calls after that.

His solution is to ditch his mocking framework (Rhino.Mocks, as far as I can tell) for that one test, and hand-roll his stub – and his example is a good case for why you might want to do that, sometimes.

However, this got me curious, and I wondered if this was indeed possible using Rhino. As recently as last week, I struggled with mocking repeat calls; but I had never actually considered a situation where one might want to mock a method, focusing only on the fact that the method is called, without paying attention to the specific arguments passed. Fun stuff.

After some digging into the documentation, I came across IgnoreArguments(), which seems to do the job:

public void SpecifyFirstReturnThenReturnSameThingForeverAfter()
{
    var fakeService = MockRepository.GenerateStub<IService>();
    fakeService.Expect(f => f.SomeMethod(null)).IgnoreArguments().Return("First").Repeat.Once();
    fakeService.Expect(f => f.SomeMethod(null)).IgnoreArguments().Return("SecondAndAfter");
    
    var first = fakeService.SomeMethod("ABC");
    var second = fakeService.SomeMethod("DEF");
    var third = fakeService.SomeMethod( "GHI" );

    Assert.AreEqual("First", first);
    Assert.AreEqual("SecondAndAfter", second);
    Assert.AreEqual("SecondAndAfter", third);
}

IgnoreArguments() seems to be a potentially convenient way to make some tests lighter. That being said, arguably, the setup here is cumbersome, and the hand-rolled version is clearer: when you reach the point where you wonder if your mock is doing what you think it should, you enter perilous territory…

by mathias 23. January 2010 00:21

One of the immediate benefits I saw in digging into F# is that it gave me a much better understanding of LINQ and lambdas in C#. Until recently, my usage of LINQ was largely limited to returning IEnumerable instead of List<T> and writing simpler queries, but I have avoided the more “esoteric” features. I realize that now that F# is becoming familiar to my brain, whenever I see a statement in C# which contains a foreach:

foreach (var item in items)
{
   // do something with item.
}

… I ask myself if this could be re-written in a more functional way. Sometimes it works, sometimes not. Just like classic OO Design Patterns, functional programming has its own patterns, and I find that having a larger toolkit of patterns in the back of my mind helps criticizing my own code and think about alternatives and possible improvements.

I encountered one such case a few days ago, with the following snippet:

public bool IsValid()
{
    foreach (var rule in this.rules)
    {
        if (!rule.IsSatisfied())
        {
            return false;
        }
    }

    return true;
}

There is nothing really wrong with this code. However, seeing the foreach statement, and an if statement with a return and no else branch made me wonder how I would have done this in F# – and my immediate thought was “I’d use a Fold”.

More...