Question

While trying to understand how Navision 5 can communicate with an external application through COM interop, i found the following example:

http://msdn.microsoft.com/en-us/library/aa973247.aspx

The second case implemented is exactly what I want to do. I tested the code (with minor modifications - added some attributes [ComVisible(true)] on the events interface and class) and with these modifications it worked as stated in the example.

However, I cannot understand why we do not get an exception on invoking the COMTimer.Elapsed through the following.

protected virtual void OnElapsed(EventArgs e)
{
  Elapsed();
}

Who is hooked to this event? The only "hook" i can see is the mTimer.Elapsed += new ElapsedEventHandler(mTimer_Elapsed); that refers to the Elapsed event of the mTimer.

Normally, Elapsed would be null in the OnElapsed function.

I would appreciate your help. Thanks in advance.

Was it helpful?

Solution

Interesting problem.

WithEvents property on automation creates the handler and attaches it to Elapsed delegate, so this one is not NULL - hence no exception

However, when WithEvents is No, and Timer.Start() is invoked, as you rightly say no exception bubbles up, even though (in theory) Elapsed delegate is null.

The simple explanation to this would be, that NAV attaches empty delegate regardless of WithEvents property. To support that, if you put code in Timer::Elapsed() trigger, then take off WithEvents, and bring it back - the code will still be there (i.e. trigger still exists in unchanged form), which makes me lean towards conclusion that it exists always (i.e. empty delegate).

But of course it's NAV so it couldn't be that simple.

I created a test codeunit from above MSDN example, but made a small change to the automation:

/// <summary>
/// Whenever the internal timer elapses, an event must be fired
/// </summary>
private void mTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    OnElapsed(EventArgs.Empty);
    throw null;
} 

This, in theory, should throw NULL whenever mTimer_Elapsed is invoked - nothing however bubbles up in NAV. I went a bit further and changed this:

///<summary>
/// Invoke the Changed event; called whenever the internal timer elapses
/// </summary>
protected virtual void OnElapsed(EventArgs e)
{
    throw new InvalidCastException("test");
    //Elapsed();
}

Again, nothing happens in NAV.

Note, that both changes behave as expected if the COM Timer is consumed from within .NET project. This makes me think, that NAV Interop must be capturing exceptions from the automation and handle them internally.

I would however pop that question in Mibuso - someone there will probably know better.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top