Hi Gary,
It’s not possible to inherit from Application in VB (I’m sure I missing something really silly)
Partial Public Class App
Inherits Application
Public Sub New()
AddHandler Windows.Threading.Dispatcher.CurrentDispatcher.UnhandledException, New System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(AddressOf App_DispatcherUnhandledException)
End Sub
Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As System.Windows.Threading.DispatcherUnhandledExceptionEventArgs)
e.Handled = True
End Sub
End Class
Unhandledable System.NullReferenceException
Ok, it was silly indeed. References to System.Windows.Application and System.Windows.Forms.Application was conflicting.
I’ll try the workaround. Will this be fixed for 6.0?
Hello Carlos,
Could you please try this code below:
Partial Public Class App
Inherits System.Windows.Application
Public Sub New()
AddHandler System.Windows.Threading.Dispatcher.CurrentDispatcher.UnhandledException, New System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(AddressOf App_DispatcherUnhandledException)
End Sub
Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As System.Windows.Threading.DispatcherUnhandledExceptionEventArgs)
e.Handled = True
End Sub
End Class
And I don't know if it will doing some changes in next release, I will confirm it.
Regards,
Gary
I don’t know why, but New() is never executed, (and hence event handler never added). I tried adding the class either in the main .exe project, and in the WPF one containing the window with the WpfMap control without success.
Anyway I already had an Addhandler with the UnhadledException and other with the UnhandledExceptionFilter in the constructor of the WPF window containing the WpfMap, and both fails to catch this particular exception.
Hey Carlos, New() is never executed probably because it is not being called anywhere. When you step into your application using F11, what is the first line of code that is executed? The constructor of that class, assuming it is App.xaml.vb should call New() or add the handler to DispatcherUnhandledException.
Hi Klaus,
I expected New() was going to be executed as it Inherits from System.Windows.Application, somehow on creating the Application (Startup)
Mi first instruction that executes is:
Partial Friend Class MyApplication
Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionFilter
AddHandler System.Windows.Forms.Application.ThreadException, AddressOf ApplicationThreadExceptionFilter
AddHandler System.Windows.Threading.Dispatcher.CurrentDispatcher.UnhandledException, New System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(AddressOf Application_DispatcherUnhandledException)
...
Where I set up all my last line of defense (just for Logging)
The problem is that System.Windows.Threading.Dispatcher.CurrentDispatcher.UnhandledException is not firing, but AppDomain.CurrentDomain.UnhandledException which has no way to resume
Hello Carlos,
Please try this code:
Imports System.Windows.Threading
Class Application
Public Sub Application()
End Sub
Public Sub OnDispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
e.Handled = True
End Sub
End Class
If you still meet problem, let us know.
Regards,
Gary
Hi Gary,
Where/how should I instantiate the class Application? What’s the difference from this code and my actual one that simply add the event handler to the Dispatcher.UnhandlerException?
AddHandler Windows.Threading.Dispatcher.CurrentDispatcher.UnhandledException, AddressOf Application_DispatcherUnhandledException
Are MapSuite component creating an additional AppDomain? This would explain why the exception is not catches
Finally, I would really really appreciate if you manage to include the workaround within the component.
Carlos.
Hello Carlos,
You can just copy this code to your default Application.xaml.cs, and I think the problem of your code is if you use some other xaml file, you need set the build action to 'ApplicationDefinition', then the program will load it and it can catch the exception.
MapSuite didn't creating an additional AppDomain, the drawing of Wpf is multithreading drawing, when the feature has deleted, but can be found in index, it will cause all background thread which fire by tile will throw exception when they do the query, and then it will effect the main thread.
You can try to set the drawing exception mode, let the main thread catch the exception and handle it, to avoid the error.
InMemoryPointsFeatureLayer.DrawingExceptionMode = DrawingExceptionMode.DrawException
Regards,
Gary
Hi Gary,
It seems that I cannot have an ApplicationDefinition file in a DLL module, and as the main application is Windows Forms instead of WPF, I cannot add it to the main app either.
DrawingExceptionMode mitigates the problem, but shows ugly red "x" on tiles while drawing.
Could you please check if it is planned to solve this issue? with 4.5 engine it was working fine, there is something broken with 5.0 (and 5.5.0.0)
TIA,
Carlos
Hello Carlos,
The different between c# project and vb project is in c# project it's name is App.xaml, vb project it's name is Application.xaml. I have attached a sample that you can have a look at.
And I don't think it's a bug because our product is a component not a executable program, we can't just handle all the exceptions and hide it. So we have DrawingExceptionMode to handle this.
And sorry I have to ask, what do you mean working fine in 4.5 version, in the sample you give us, that code will cause exception in 4.5 too.
Regards,
Gary
002_001_WpfApplication1.zip (15.6 KB)
Hi Gary,
The sample I provided was a mere simplification to show the issue. The real case is not that simple, I don’t refresh the Overlay until I rebuild the index, but mine is a multithreaded application, so other thread might be trying to refresh the overlay before this thread finished updating the InternalFeatures, and hence the exception occurs.
I’m not asking you to handle all the exceptions, but a missing or incomplete Index should not thow an exception, but have impact on performance or spatial queries (i.e. FindFeaturesNearTo might fail).
With 4.5 engine my application had no issues at all, but after upgrading to 5.0 (and now to 5.5) some users experience this NullReferenceException when refreshing some times. I guess it’s because MapSuite internal changes on multithreaded drawing introduced with 5.0
Hello Carolos,
We have been unable to recreate the issue where the NullReferenceException occurs when refreshing using the 5.5 version. Without being able to recreate the issue we are having difficulties in resolving the issue.
While I know it’s difficult for you to break out the logic from your main applicaiton into a simple sample there must be something different happening in your application causing the exception.
Can you put together a sample that replicates what your app is doing to try and make the issure recreatable? Once it’s easy to recreate we should be able to fix it very quickly.
Regards,
Gary
Hi Gary,
I had this issue parked for a while, and now I’m retaking it.
The issue was that if a WPF window is instantiated and launched from a base Windows Forms application, DispatcherUnhandlerException filter not always work as exposed above.
To overcome this, I just created a WPF application that launch the WpfMap window so your code can catch the exception (NullReferenceException until now)
What I receive now that the exception is catches is:
System.Collections.Generic.KeyNotFoundException: La clave proporcionada no se encontró en el diccionario.
en ThinkGeo.MapSuite.WpfDesktopEdition.Tile.<>c__DisplayClass2.<DrawException>b__0()
en System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
en MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
As you can see Stack trace says very little what is going on inside Tile class.
Any idea?
Forget it!
Striping down my code to create a simple example I figured out that the cause was an InMemoryFeatureLayer.InternalFeature that was removed by one thread, and before it had time to rebuild the index other one was calling Refresh, causing this exception.
I wouldn’t expect an exception to be thrown if index is not build yet, but just a feature that is not draw or spatially taken in consideration. Do you plan to fix this internal issue?
Hello Carlos,
Truly thanks for your further information.
So this is a reason I suggest use EditTools instead of InternalFeature, EditTools will automatically rebuild the index.
Also we will deep digging this thread problem and see if we can fix this.
Regards,
Gary
Hi Gary,
EditTools has the same performance penalty as building the index by myself each time I add or remove an internal feature.
What is nice is to be able to add (or remove) a bunch of Features and then Build the index later, but this must be "thread safe"
Regards,
Carlos
Please keep me updated on the progress of the improvement.
Hi Gary,
In addition to the x4 performance degradation you get by building index every time you add or remove a feature, EditTools has other disadvantages that makes it useless at least for me: you cannot include a “Key” when you add a feature, it have no Contains method to know if a Feature is already included, and you cannot Clear the FeatureLayer.
I’m opening a support Ticket today to have the InternalFeatures issue fixed.
Carlos
Hello Carlos,
Thanks for your further information and suggestion, we will working on this and dig in to find a solution.
Regards,
Gary
Hello Carlos,
Thanks for your further information and suggestion, we will working on this and dig in to find a solution.
Regards,
Gary