Semantic Logging Application Block preventing application from shutting down

Topics: Semantic Logging Application Block
Feb 6, 2014 at 3:56 AM
SLAB 1.0.1304.0 (per NuGet), Visual Studio 2013, .NET framework 4.5.1, WPF, Prism 4.1.0.0

It doesn't happen every time, but probably 60-70% of the time I have to kill my application using VS's "Stop" button (when debugging), or Process Explorer (when running stand-alone). Before I stop the application in VS, if I "break all" (the pause button) to see where things are hanging, it's always on a call to ObservableEventListener.Dispose()

I followed the documentation very closely when setting things up, but let me know the important stuff to confirm. Everything seems to start and run well. Shutdown is the problem.

I have 6 ObservableEventListeners new'd up as Application fields. In my Application.OnExit override I call Shutdown on my EventSource, then for each OEL I call DisableEvents, and finally I Dispose each.

Any ideas on where to start looking? Thanks
Feb 14, 2014 at 8:16 PM
ping
Feb 16, 2014 at 6:48 AM
It sounds like during buffer flushing there may be some locking issue but it's hard to determine without more details. Can you provide a sample application that demonstrates the issue (even if just occasionally)?

Thanks,

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 16, 2014 at 1:33 PM
Edited Feb 16, 2014 at 1:34 PM
I'll try and find some time to pull a full demo together. In the meantime, I have commented out the clean-up lines below (see OnExit) and I haven't seen the issue ... anything wrong with just not doing the cleanup work?

WPF application w/ Prism, Unity (latest versions of each)
public partial class App : Application
    {
        ObservableEventListener LogListener1 = new ObservableEventListener();
        ObservableEventListener LogListener2 = new ObservableEventListener();
        ObservableEventListener LogListener3 = new ObservableEventListener();
        ObservableEventListener LogListener4 = new ObservableEventListener();
        ObservableEventListener LogListener5 = new ObservableEventListener();
        ObservableEventListener LogListenerApp = new ObservableEventListener();

        protected override void OnStartup( StartupEventArgs e ) {
            base.OnStartup( e );

            ConfigureLogging();
            SgcEventSource.Log.Startup( new Microsoft.VisualBasic.ApplicationServices.ApplicationBase().Info.Version.ToString() );

            // the bootstrapper will create the shell/main window instance, so
            // the App.xaml does not have a startup.uri
            LPNGatewayBootstrapper bootstrapper = new LPNGatewayBootstrapper();
            bootstrapper.Run();
        }

        protected override void OnExit( ExitEventArgs e ) {
            base.OnExit( e ); 

            SgcEventSource.Log.Shutdown( e.ApplicationExitCode );

            //LogListener1.DisableEvents( SgcEventSource.Log );
            //LogListener2.DisableEvents( SgcEventSource.Log );
            //LogListener3.DisableEvents( SgcEventSource.Log );
            //LogListener4.DisableEvents( SgcEventSource.Log );
            //LogListener5.DisableEvents( SgcEventSource.Log );
            //LogListenerApp.DisableEvents( SgcEventSource.Log );

            //LogListener1.Dispose();
            //LogListener2.Dispose();
            //LogListener3.Dispose();
            //LogListener4.Dispose();
            //LogListener5.Dispose();
            //LogListenerApp.Dispose();
        }

        private void ConfigureLogging() {
            LogListener1.EnableEvents( SgcEventSource.Log, EventLevel.LogAlways, SgcEventSource.Keywords.Gateway1 | SgcEventSource.Keywords.Application );
            LogListener2.EnableEvents( SgcEventSource.Log, EventLevel.LogAlways, SgcEventSource.Keywords.Gateway2 | SgcEventSource.Keywords.Application );
            LogListener3.EnableEvents( SgcEventSource.Log, EventLevel.LogAlways, SgcEventSource.Keywords.Gateway3 | SgcEventSource.Keywords.Application );
            LogListener4.EnableEvents( SgcEventSource.Log, EventLevel.LogAlways, SgcEventSource.Keywords.Gateway4 | SgcEventSource.Keywords.Application );
            LogListener5.EnableEvents( SgcEventSource.Log, EventLevel.LogAlways, SgcEventSource.Keywords.Gateway5 | SgcEventSource.Keywords.Application );
            LogListenerApp.EnableEvents( SgcEventSource.Log, EventLevel.LogAlways, SgcEventSource.Keywords.Application );

            string logFolder = @"C:\Logging\LPNGateway\";

            LogListener1.LogToRollingFlatFile( Path.Combine( logFolder, @"Gateway1\Gateway1.log" ), 500, "yyyy-MM-dd", RollFileExistsBehavior.Increment, RollInterval.Midnight, new SgcEventTextFormatter(), 500, true );
            LogListener2.LogToRollingFlatFile( Path.Combine( logFolder, @"Gateway2\Gateway2.log" ), 500, "yyyy-MM-dd", RollFileExistsBehavior.Increment, RollInterval.Midnight, new SgcEventTextFormatter(), 500, true );
            LogListener3.LogToRollingFlatFile( Path.Combine( logFolder, @"Gateway3\Gateway3.log" ), 500, "yyyy-MM-dd", RollFileExistsBehavior.Increment, RollInterval.Midnight, new SgcEventTextFormatter(), 500, true );
            LogListener4.LogToRollingFlatFile( Path.Combine( logFolder, @"Gateway4\Gateway4.log" ), 500, "yyyy-MM-dd", RollFileExistsBehavior.Increment, RollInterval.Midnight, new SgcEventTextFormatter(), 500, true );
            LogListener5.LogToRollingFlatFile( Path.Combine( logFolder, @"Gateway5\Gateway5.log" ), 500, "yyyy-MM-dd", RollFileExistsBehavior.Increment, RollInterval.Midnight, new SgcEventTextFormatter(), 500, true );
            LogListenerApp.LogToRollingFlatFile( Path.Combine( logFolder, "Application.log" ), 1000, "yyyy-MM-dd", RollFileExistsBehavior.Increment, RollInterval.Midnight, new SgcEventTextFormatter(), 500, true );
        }
    }
Feb 18, 2014 at 2:43 PM
Since the AppDomain (and process) is just about to be torn down I don't see a problem with not performing the cleanup at that point since all resources should be released on exit.

I'm assuming the hanging is always on a different call to Dispose and not the same listener.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 18, 2014 at 3:26 PM
Yes, your assumption is correct. The hang seems to jump around between the various Dispose calls

Sent from Mailbox for iPhone