I continue working on my TCP sockets, as mentioned this morning.
I have discovered that the amount of sockets keeps growing, every time I send a message over such a socket. This simply means that I am constantly creating and opening new sockets instead of re-using the already opened ones.
In my application, I have a repository of connections, and I only need to use one of them. But I'm afraid that I'm constantly creating new ones. This is the way it is done:
public static class Repository
{
...
public static Conn GetByName(string name, ...)
{
return result =
context.Set<Conn>().Where(o => o.Name == name).FirstOrDefault();
}
}
...
Conn Connection_For_Message = Repository.GetByName(request.ConnectionName, ...);
According to me:
- The fact that the
Repository
is declaredstatic
causes one single object to be created internally. - As the
GetByName()
method performs aFirstOrDefault()
of aWhere()
method, this is giving the already existing object, and it does not create a new one.
Now I have the impression that 1. is correct, but 2. is wrong, in the sense that Connection Connection_For_Message
always creates a new instance of an object.
Is my impression correct and if yes, how can I solve this? I was thinking of altering Repository
from a static class into a singleton, but I don't find an ISingleton
or something in System.Reflection
, or am I looking the completely wrong direction?
Edit: Hereby a part of the constructor of the Conn
class:
public Conn(...)
{
...
TcpConnection = new TcpConnection(...); // in here a
...
}
As far as the TcpConnection
class is concerned:
public class TcpConnection : IDisposable
{
public Socket _socket;
...
Every time I send a message, I pass by the GetByName()
method and my call stack looks as follows:
My_Application.dll!TcpConnection.TcpConnection(...) Line 39 C#
> My_Application.dll!Conn.Conn(...) Line 32 C#
[External Code]
My_Application.dll!ConnectionRepository.GetByName(string name, ...) Line 71 C#
The line, marked with >
is the constructor, which proves indeed that GetByName()
is calling the Conn
constructor indeed. (Oh, and why is there "External code" between the GetByName()
method and the constructor?)
Edit again: I have managed showing the external code, hereby the callstack with "Show External Code" checked:
> My_Application.dll!TcpConnection.TcpConnection(...) Line 39 C#
My_Application.dll!Conn.Conn(...) Line 32 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Private.CoreLib.dll!System.Reflection.RuntimeConstructorInfo.Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) C#
System.Private.CoreLib.dll!System.RuntimeType.CreateInstanceImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture) C#
System.Private.CoreLib.dll!System.Activator.CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) C#
Castle.Core.dll!Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(System.Type proxyType, System.Collections.Generic.List<object> proxyArguments, System.Type classToProxy, object[] constructorArguments) C#
[Lightweight Function]
Microsoft.EntityFrameworkCore.Relational.dll!Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable<Conn>.Enumerator.MoveNext() C#
System.Linq.dll!System.Linq.Enumerable.TryGetSingle<Conn>(System.Collections.Generic.IEnumerable<Conn> source, out bool found) C#
[Lightweight Function]
System.Linq.Queryable.dll!System.Linq.Queryable.FirstOrDefault<Conn>(System.Linq.IQueryable<Conn> source) C#
My_Application.dll!ConnectionRepository.GetByName(string name, ...) Line 71 C#
Repository
, and can't be. – InfuseGetByName
that obviously creates new instances ofConn
. We don't know whatcontext.Set<Conn>
does though - maybe that call creates new instances... – Infusestatic
does nearly nothing. And I don't understand, does this question have anything do withReflection
? – PiroshkiGetByName()
passes via the constructor of theConn
, I have checked this using the debugger, I'll edit my question immediately. – CarsickReflection
: I thought finding theISingleton
interface in there, but that was a bad hunch. – CarsickSystem.LinQ
), so I'm wondering if creating a new list ofConn_with_socket
objects wouldn't cause the same issue while querying? – CarsickConcurrentDictionary<string, TcpConnection>
dictionary to manage your connections, or something similar (but first check how to useConcurrentDictionary
correctly, or use normalDictionary
and use locks). – DiscountList<Conn>
byConcurentDictionary<string, ...>
and launchingTryGetValue()
does not launch the constructor anymore, so this is working. Please rewrite your comment as an answer, I'll accept, upvote and reward it, your reputation will take a jump of 225 points :-) – Carsick