Cannot access a disposed object. Object name: 'System.Net.Sockets.TcpClient'.
I don't understand why it happen and how to deal with it. I use Ninject, my application is based on mvcstarter.codeplex.com/ what I do is delete some user or pages from my database and it happen for no reason(that I can find).
Any help would be appreciated!
Thanks a lot!
*Edited Also, after a while it get back to normal and I can fetch my data from Mongo... My unit tests work fine...
Here's my code for my session :
public class MongoSession : ISession{
private readonly Mongo _server;
public MongoSession()
{
//this looks for a connection string in your Web.config - you can override this if you want
_server = Mongo.Create("MongoDB");
}
public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class {
return _server.GetCollection<T>().AsQueryable().Where(expression).SingleOrDefault();
}
public IQueryable<T> All<T>() where T : class {
return _server.GetCollection<T>().AsQueryable();
}
/*public void Add<T>(T item) where T : class {
_provider.DB.GetCollection<T>().Insert(item);
}*/
public void Save<T>(IEnumerable<T> items) where T : class {
foreach (T item in items) {
Save(item);
}
}
public void Save<T>(T item) where T : class {
var errors = DataAnnotationsValidationRunner.GetErrors(item);
if (errors.Count() > 0)
{
throw new RulesException(errors);
}
_server.Database.GetCollection<T>().Save(item);
}
//this is just some sugar if you need it.
/*public T MapReduce<T>(string map, string reduce) {
T result = default(T);
using (MapReduce mr = _provider.Server.CreateMapReduce()) {
MapReduceResponse response =
mr.Execute(new MapReduceOptions(typeof(T).Name) {
Map = map,
Reduce = reduce
});
MongoCollection<MapReduceResult<T>> coll = response.GetCollection<MapReduceResult<T>>();
MapReduceResult<T> r = coll.Find().FirstOrDefault();
result = r.Value;
}
return result;
}*/
public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
{
var items = All<T>().Where(expression);
foreach (T item in items)
{
Delete(item);
}
}
public void Delete<T>(T item) where T : class
{
_server.GetCollection<T>().Delete(item);
}
public void Drop<T>() where T : class
{
_server.Database.DropCollection(typeof(T).Name);
}
/*public void CommitChanges()
{
//mongo isn't transactional in this way... it's all firehosed
}*/
public void Dispose() {
_server.Dispose();
}
}
And the calling code would be something like this, my _session is pass to my Controller in the contrutor using Ninject, with the binding in my global.cs :
Bind<ISession>().To<MongoSession>().InSingletonScope();
public virtual ActionResult Liens()
{
var shortcutLionks = _session.All<ShortcutLinks>().ToList();
ViewData.Model = shortcutLionks.Count > 0 ? shortcutLionks[0] : new ShortcutLinks();
return View();
}
EDITED :
Here's the detail of my error :
Stack Trace : at System.Net.Sockets.TcpClient.GetStream() at Norm.Connection.GetStream() at Norm.Connection.Write(Byte[] bytes, Int32 start, Int32 size) at Norm.Protocol.Messages.QueryMessage
2.Execute() at Norm.MongoQueryExecutor
3.d__0.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 source) at Norm.Linq.MongoQueryExecutor.Execute[T]() at Norm.Linq.MongoQueryProvider.ExecuteQuery[T](Expression expression) at Norm.Linq.MongoQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable
1 source) at Domain.Storage.MongoDB.MongoSession.Single[T](Expression1 expression) in C:\inetpub\wwwroot\DubeLoiselle\Domain\Storage\MongoDB\MongoSession.cs:line 21 at Domain.Storage.MongoDB.MongoRepositoryBase
1.Single(Expression1 expression) in C:\inetpub\wwwroot\DubeLoiselle\Domain\Storage\MongoDB\MongoRepositoryBase.cs:line 26 at SPK.CMS.Domain.Repository.PageRepository.GetHomePage() in C:\inetpub\wwwroot\DubeLoiselle\SPK.CMS.Domain\Repository\PageRepository.cs:line 146 at Web.Controllers.PageController.Home() in C:\inetpub\wwwroot\DubeLoiselle\Web\Controllers\PageController.cs:line 26 at Web.Controllers.PageController.RedirectTo(String url1, String url2, String url3) in C:\inetpub\wwwroot\DubeLoiselle\Web\Controllers\PageController.cs:line 50 at lambda_method(ExecutionScope , ControllerBase , Object[] ) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.b__a() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func
1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary
2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
Edited again :
Before I get this error I trap this one :
Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.
Stack Trace : at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size) at Norm.Connection.Write(Byte[] bytes, Int32 start, Int32 size) at Norm.Protocol.Messages.QueryMessage2.Execute() at Norm.MongoQueryExecutor
3.d__0.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 source) at Norm.Linq.MongoQueryExecutor.Execute[T]() at Norm.Linq.MongoQueryProvider.ExecuteQuery[T](Expression expression) at Norm.Linq.MongoQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable
1 source) at Domain.Storage.MongoDB.MongoSession.Single[T](Expression1 expression) in C:\inetpub\wwwroot\DubeLoiselle\Domain\Storage\MongoDB\MongoSession.cs:line 21 at Domain.Storage.MongoDB.MongoRepositoryBase
1.Single(Expression1 expression) in C:\inetpub\wwwroot\DubeLoiselle\Domain\Storage\MongoDB\MongoRepositoryBase.cs:line 26 at SPK.CMS.Domain.Repository.PageRepository.GetHomePage() in C:\inetpub\wwwroot\DubeLoiselle\SPK.CMS.Domain\Repository\PageRepository.cs:line 146 at SPK.CMS.Domain.Repository.PageRepository.GetByUrl(String url1, String url2, String url3) in C:\inetpub\wwwroot\DubeLoiselle\SPK.CMS.Domain\Repository\PageRepository.cs:line 195 at Web.Controllers.PageController.RedirectTo(String url1, String url2, String url3) in C:\inetpub\wwwroot\DubeLoiselle\Web\Controllers\PageController.cs:line 52 at lambda_method(ExecutionScope , ControllerBase , Object[] ) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.b__a() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func
1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary
2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
I found a solution for this problem, I close my Session object in my controller in the OnActionExecuted()
Hope it can helps someone else!
It happens because the underlying TcpClient have been disconnected from the server.
You should open an
IMongo
connection at the last moment, only to query the NoSQL datastore and dispose it. There is a connection pool that keeps connections opened and remove dead connections to lower the cost of usingMongo.Create
.Keeping connection opened for too long will cause you problems when you'll have many clients simultaneously.