退出后,嵌入式服务器应用程序停止工作

whi*_*key 5 c# entity-framework unhandled-exception firebird-embedded

我有一个应用程序,它将一些数据存储在firebird数据库中.我正在使用嵌入式火鸟服务器和EntityFramework,并且所有工作都非常好但是当我通过表单上的x按钮关闭我的应用程序时,我得到一个Windows系统消息"应用程序已停止工作",我无法捕获此异常.我的应用程序中有一个UnhandledExceptionHandler:

// 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());
Run Code Online (Sandbox Code Playgroud)

但这种例外从来没有被它抓住过.所以我去了windows事件日志,发现有错误事件的xml-view:

- <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>
Run Code Online (Sandbox Code Playgroud)

当app已经关闭时,你看到fbintl.DLL出了问题.那我怎么能得到关于这个问题的更详细的描述呢?

UPD 我使应用程序更短,以检测我的问题的原因 - 现在只有这个EF代码在应用程序关闭之前运行

 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

FirebirdDbContext的位置是:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和连接参数是

  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();
    }
Run Code Online (Sandbox Code Playgroud)

新更新25.04.2017

我用firebird嵌入式数据库制作了一个简单的应用程序来演示错误.你可以在这里找到它

该应用程序创建一个firebird嵌入式数据库并在后台线程(任务TPL)连接到它,并在工作完成后(_bgTask.Status == TaskStatus.RanToCompletion)你关闭应用程序并得到错误.

sta*_*ica 4

在连接字符串中,您已指定字符集并启用连接池:

\n\n
FbConnectionStringBuilder builder = new FbConnectionStringBuilder\n{\n    \xe2\x80\xa6\n    Charset = "WIN1251",\n    \xe2\x80\xa6\n    Pooling = true,\n    \xe2\x80\xa6\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

这两个设置的组合似乎会触发错误;不是在您自己的代码中,而是在 FirebirdSQL 中。到目前为止,我已经找到了三种方法来解决这个问题。您可以执行以下任一操作:

\n\n
    \n
  1. 在应用程序终止之前调用静态FbConnection.ClearAllPools()方法(并启用连接池):

    \n\n
    private static void AppExit(object sender, EventArgs e)\n{\n    \xe2\x80\xa6\n    FbConnection.ClearAllPools();\n}\n
    Run Code Online (Sandbox Code Playgroud)
  2. \n
  3. 通过设置禁用连接池Pooling = false

  4. \n
  5. 由于错误是在 中触发的fbintl.dll,它似乎正在处理字符集/国际化,因此您可以简单地省略Charset连接字符串参数(尽管我不知道这会产生什么后果)。

  6. \n
\n\n

最后两个建议是解决方法。我可能会选择选项#1,因为它似乎是最干净的,允许您保持连接池启用(这通常是一件好事),并指定您需要的字符集。

\n\n

另请注意,如果您在附加调试器的情况下运行应用程序,您可能只会看到异常。在生产中,异常很可能保持沉默并完全被忽视。

\n