Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded server application has stopped working after exit

I have an application that stores some data in firebird database. I'm using an embedded firebird server and EntityFramework and all works greatfully but when I close my app by x button on form I get a windows system message "application has stopped working" and I can't catch this exception. I have an UnhandledExceptionHandler in my app :

// Add handler for UI thread exceptions
Application.ThreadException += new ThreadExceptionEventHandler(UIThreadException);

// Force all WinForms errors to go through handler
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

//This handler is for catching non-UI thread exceptions 
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

.....some other code..........

Application.Run(new MainForm());

But this kind of exception never been catched by it. So I went to windows event log and found there this xml-view of error-event :

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Application Error" /> 
  <EventID Qualifiers="0">1000</EventID> 
  <Level>2</Level> 
  <Task>100</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2017-03-14T23:06:25.000000000Z" /> 
  <EventRecordID>36077</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>MYPC</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data>MyApp.exe</Data> 
  <Data>1.0.0.0</Data> 
  <Data>58c7a3f0</Data> 
  <Data>fbintl.DLL</Data> 
  <Data>2.5.5.26952</Data> 
  <Data>5644432f</Data> 
  <Data>c0000005</Data> 
  <Data>00004e9c</Data> 
  <Data>1d64</Data> 
  <Data>01d29d1797fb7f0d</Data> 
  <Data>G:\Programming\WorkSpace\C#\MyApp\bin\x86\Debug\MyApp.exe</Data>
  <Data>G:\Programming\WorkSpace\C#\MyApp\bin\x86\Debug\FireBirdEmbeddedServer\intl\fbintl.DLL</Data> 
 <Data>d84a6ca6-090a-11e7-8151-005056c00008</Data> 
 </EventData>
 </Event>

As you see something went wrong with fbintl.DLL when app has closed already. So how I can get more detailed description about this problem?

UPD I make an app more shorter to detect a reason of my problem - now ONLY this EF code runs before app close

 public async Task GetAutoAnswerTemplate()
    {           
       try
        {
          using (var db = new FirebirdDbContext(embeddedConnectionString)){
            //Async or sync methods doesn't affect to my problem
             AutoAnswerTemplate template = await dbContext.AutoAnswerTemplate.FirstOrDefaultAsync();
            return template?.AutoAnswer_body;
          }
        }
        catch (Exception ex)
        {
            throw new EmbeddedFbDataBaseTools.EmbeddedDbException(
                "Error while getting auto answer template" + "\r\n" +  ex.Message, ex);
        }
    }

Where FirebirdDbContext is :

public class FirebirdDbContext : DbContext
{

    public FirebirdDbContext(string connString)
        : base(new FbConnection(connString), true)
    {
        //* The Entity initializer is bugged with Firebird embedded: http://stackoverflow.com/q/20959450/2504010  so I didn't use default--->
        //  Database.SetInitializer<FirebirdDBContext>(new CreateDatabaseIfNotExists<FirebirdDBContext>());    
        Database.SetInitializer<FirebirdDbContext>(new MyCreateDatabaseIfNotExists());
    }

    public DbSet<AutoAnswerTemplate> AutoAnswerTemplate { get; set; }
    public DbSet<User> User { get; set; }


}

class MyCreateDatabaseIfNotExists : IDatabaseInitializer<FirebirdDbContext>
{
    public void InitializeDatabase(FirebirdDbContext context)
    {
        if (!context.Database.Exists())
        {
            context.Database.Create();
        }
    }
}

And connection params is

  public static string GetEmbeddeddefaultConnectionString()
    {
        FbConnectionStringBuilder builder = new FbConnectionStringBuilder
        {
            ServerType = FbServerType.Embedded,
            DataSource = "localhost",
            Port = 3050,
            Database = EmbeddedDbPath, //Path to embedded db
            ClientLibrary = EmbeddedServerDllPath,
            UserID = "SYSDBA",
            Password = "masterkey",
            Charset = "WIN1251",
            Dialect = 3,
            ConnectionLifeTime = 15,
            Pooling = true,
            MinPoolSize = 0,
            MaxPoolSize = 50
        };
        return builder.ToString();
    }

NEW UPDATE 25.04.2017

I made a simple app with firebird embedded db that demonstrates the error. U can find it here

The app creates a firebird embedded database and connects to it in background thread (Task TPL), and after work is done (_bgTask.Status == TaskStatus.RanToCompletion) u close the app and get the error.

like image 528
whizzzkey Avatar asked Mar 14 '17 23:03

whizzzkey


Video Answer


2 Answers

In your connection string, you have specified a character set and enabled connection pooling:

FbConnectionStringBuilder builder = new FbConnectionStringBuilder
{
    …
    Charset = "WIN1251",
    …
    Pooling = true,
    …
};

The combination of these two settings appears to trigger the error; not in your own code, but in FirebirdSQL's. I have so far found three ways to resolve this issue. You can do either of these:

  1. Call the static FbConnection.ClearAllPools() method right before your application terminates (and leave connection pooling enabled):

    private static void AppExit(object sender, EventArgs e)
    {
        …
        FbConnection.ClearAllPools();
    }
    
  2. Disable connection pooling by setting Pooling = false.

  3. Since the error is triggered in fbintl.dll, which appears to be dealing with character sets / internationalization, you can simply omit the Charset connection string parameter (though I do not know what consequences this would have).

The last two suggestions are workarounds. I would probably go with option #1 as it seems to be cleanest, allows you to keep connection pooling enabled (which is usually a good thing), and specify the charset you need.

Note also that you might only ever see the exception if you run your application with a debugger attached. In production, the exception might well stay silent and go completely unnoticed.

like image 149
stakx - no longer contributing Avatar answered Nov 15 '22 06:11

stakx - no longer contributing


Your exception handling shoud work except in 2 cases, stack overflow exceptions and memory exceptions. In this cases the behaviour should be the behaviour you described (system message "application has stopped working").
About stack overflow exceptions, with EF happens quite often when you serialize entities (json, xml, ...) with lazy load enabled. Are you serializing entities during exit?

If this is not your case you could check other two things:

  • do you ever detach the two event handlers?
  • are you causing exceptions in the exception handler?
like image 37
bubi Avatar answered Nov 15 '22 06:11

bubi