簡體   English   中英

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

[英]Embedded server application has stopped working after exit

我有一個應用程序,它將一些數據存儲在firebird數據庫中。 我正在使用嵌入式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());

但這種例外從來沒有被它抓住過。 所以我去了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>

當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);
        }
    }

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();
        }
    }
}

和連接參數是

  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();
    }

新更新25.04.2017

我用firebird嵌入式數據庫制作了一個簡單的應用程序來演示錯誤。 你可以在這里找到它

該應用程序創建一個firebird嵌入式數據庫並在后台線程(任務TPL)連接到它,並在工作完成后(_bgTask.Status == TaskStatus.RanToCompletion)你關閉應用程序並得到錯誤。

在連接字符串中,您已指定了字符集並啟用了連接池:

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

這兩個設置的組合似乎會觸發錯誤; 不是在你自己的代碼中,而是在FirebirdSQL中。 到目前為止,我找到了三種方法來解決這個問題。 您可以執行以下任一操作:

  1. 在應用程序終止之前調用靜態FbConnection.ClearAllPools()方法 (並啟用連接池):

     private static void AppExit(object sender, EventArgs e) { … FbConnection.ClearAllPools(); } 
  2. 通過設置Pooling = false禁用連接池

  3. 由於錯誤是在fbintl.dll觸發的,這似乎是處理字符集/國際化,你可以簡單地省略Charset連接字符串參數 (雖然我不知道這會產生什么后果)。

最后兩個建議是解決方法。 我可能會選擇#1,因為它似乎是最干凈的,允許你保持連接池(這通常是一件好事),並指定你需要的字符集。

另請注意,如果在附加調試器的情況下運行應用程序,則可能只會看到異常。 在生產中,異常可能會保持沉默並完全不被注意。

除了2種情況,堆棧溢出異常和內存異常外,您的異常處理工作正常。 在這種情況下,行為應該是您描述的行為(系統消息“應用程序已停止工作”)。
關於堆棧溢出異常,當您在啟用延遲加載的情況下序列化實體(json,xml,...)時,會經常發生EF。 您是在退出時序列化實體嗎?

如果不是這種情況,您可以檢查其他兩件事:

  • 你有沒有拆分這兩個事件處理程序?
  • 你在異常處理程序中導致異常嗎?

調試代碼有點棘手_prepareAppTask = new TaskFactory().StartNew會不時導致競爭條件,這反過來導致我在原始帖子中描述的異常。

當我嘗試在主線程中運行DB代碼時導致意外行為並使我解決了問題的事情,你在幕后拋出並捕獲和異常並不明顯。

除此之外,我沒有在您的代碼中看到任何可能導致錯誤的關鍵問題。 似乎firebird本身或EF提供程序導致應用程序關閉時出現問題。 它與同步或異步代碼無關 - 不是那樣的。 我只需運行控制台應用程序即可重現它。

只有在創建數據庫連接並且代碼訪問數據庫時,應用程序才會在退出時使用錯誤模塊名稱:fbintl.DLL崩潰。 錯誤模塊的答案是什么意思,為什么會發生這種情況? 讓我覺得問題是使用firebase還是使用EF提供程序。

你有沒有嘗試過其他方式連接到firebase?

如果你只需要擺脫那個令人討厭的異常,那么這個hack對我有用:

private static void AppExit(object sender, EventArgs e)
{
    ...
    // To ensure pending DB operations are processed. Not sure that's needed.
    int timeout = 1000;
    Thread.Sleep(timeout);
    Process.GetCurrentProcess().Kill();
}

在退出之前立即終止進程可防止錯誤顯示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM