2015-09-21 74 views
4

我剛剛開始將MongoDB集成到我的應用程序中,並且遇到了一些問題。在我的應用程序中,我使用最新的2.1版本的MongoDB C#驅動程序,並僅使用MongoDB進行應用程序日誌記錄。正確關閉來自C#2.1驅動程序的MongoDB數據庫連接?

當前顯示我的主要應用程序Form我首先檢查,看看mongod.exe是否正在運行,如果沒有,我開始它。然後當我的主要Form顯示它打開一個連接數據庫使用下面看到。

public void Open() 
{ 
    Client = new MongoClient("mongodb://localhost:27017"); 
    Database = Client.GetDatabase(DBName); 
    Collection = Database.GetCollection<BsonDocument>(ColName); 
} 

我的問題是當我的應用程序關閉時應如何正確關閉此連接?

也有考慮我應該考慮在離開mongod.exe運行與每次關閉應用程序時退出嗎?

我已經搜索了幾次試圖找出是否有正確的方式來關閉連接,但沒有發現任何非常具體的。有一箇舊的SO帖子(我現在無法找到)提到.Dispose方法,儘管我似乎無法在最新的驅動程序中找到它,也沒有從我的IDE的自動完成中找到它。

回答

11

截至今天的MongoDB版本(v2.0.1.27MongoDB.Driver),沒有必要關閉或處理連接。客戶端自動處理它。

the docs

甲MongoClient對象將是根對象。它是線程安全的,並且是處理連接到服務器,監視服務器以及對這些服務器執行操作所需的全部功能。 [...] 建議將MongoClient實例存儲在全局位置,作爲靜態變量或存儲在具有單例生命週期的IoC容器中。但是,使用相同設置創建的多個MongoClient實例將在下面使用相同的連接池。

有一個線程安全的MongoDB類的部分/舊列表in this SO answer

+0

這就是我處理我的'IMongoClient'的方式,它是在我的應用程序可以訪問的單例記錄類中。我想這個答案也基本上說服了我,它不需要特別的關閉它。 //儘管我仍然不確定是否應該在應用程序關閉後繼續運行Mongo守護進程。 – KDecker

1

的問題似乎已經被還挺問這裏的When should i be opening and closing MongoDB connections?

如果它接受的答案,

我將離開開放的連接重新建立的連接 昂貴。 Mongo很好,有很多連接,開放很長時間。 理想情況下,您應該做的是與應用程序的所有部分 共享作爲持久連接的連接。 C#驅動程序應該足夠聰明,可以自己完成這項工作,這樣它就不會創建太多的連接,因爲它在內部使用「連接池」,即使連接池重新使用連接也不例外。該文檔說:「連接到服務器後自動處理(連接 池用於提高效率)。」

對你來說工作的很好,那麼一切都很好。即使是MongoDB的C#駕駛quick tour page lends the same advice -

通常你只在一定的集羣 創建一個MongoClient實例,並在您的應用程序中使用它。但是,創建多個MongoClients 將仍然共享相同的連接池,當且僅當連接字符串相同時 。


否則,我認爲你可以簡單地把你的電話創建一個using(){}代碼塊的連接。它自動爲你調用dispose方法(因爲它實現了IDisposable模式)。你應該使用這個塊來處理你想要處理的資源。

+0

我看到了這個問題的答案,但它是朝着有多個'IMongoClient's對如何正確地關閉它們更適應。我認爲ashes999大部分回答如下。 //儘管我仍然不確定是否應該在應用程序關閉後繼續運行Mongo守護進程。 – KDecker

+0

@KDecker:我看不出其他答案和我的區別。無論如何,即使關閉連接,MongoDB的角度也不會影響連接。您可以關閉它,讓您放心。 – displayName

0

根據我的經驗,正確的方法就像回答,但即使遵循這些建議,我仍然有隨機EndOfStreamException。看起來有些問題是由互聯網提供商在一段時間後關閉連接引起的。

我解決它通過添加:

MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString)); 
      settings.SslSettings = new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 }; 
      settings.MaxConnectionIdleTime = TimeSpan.FromSeconds(30);