Dom*_*que 5 c# singleton static callstack scope
正如今天早上提到的,我继续研究我的 TCP 套接字。
我发现每次我通过这样的套接字发送消息时,套接字的数量都会不断增加。这仅仅意味着我不断创建和打开新的套接字,而不是重新使用已经打开的套接字。
在我的应用程序中,我有一个连接存储库,我只需要使用其中一个。但我担心我会不断地创造新的。这是它的完成方式:
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, ...);
Run Code Online (Sandbox Code Playgroud)
据我说:
Repository声明 的事实static会导致在内部创建一个对象。GetByName()方法执行某个FirstOrDefault()方法时Where(),这会给出已经存在的对象,并且不会创建新的对象。现在我的印象是 1. 是正确的,但 2. 是错误的,因为Connection Connection_For_Message 总是创建一个对象的新实例。
我的印象是否正确?如果是,我该如何解决这个问题?我正在考虑Repository从静态类更改为单例,但我没有找到ISingleton或 中的东西System.Reflection,或者我正在寻找完全错误的方向?
编辑:这是该类构造函数的一部分Conn:
public Conn(...)
{
...
TcpConnection = new TcpConnection(...); // in here a
...
}
Run Code Online (Sandbox Code Playgroud)
就TcpConnection班级而言:
public class TcpConnection : IDisposable
{
public Socket _socket;
...
Run Code Online (Sandbox Code Playgroud)
每次发送消息时,我都会传递该GetByName()方法,并且我的调用堆栈如下所示:
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#
Run Code Online (Sandbox Code Playgroud)
标记为>构造函数的行,这证明确实GetByName()正在调用Conn构造函数。GetByName()(哦,为什么方法和构造函数之间有“外部代码” ?)
再次编辑:我已成功显示外部代码,因此选中“显示外部代码”的调用堆栈:
> 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#
Run Code Online (Sandbox Code Playgroud)
您正在使用实体框架查询数据库以获取 Conn(正如我们从调用堆栈中看到的那样)。数据库当然不能存储TCP连接之类的东西。每次执行查询时,都会返回 Conn 的新实例(从技术上讲,它可以从缓存返回,但不会改变情况),尽管它代表相同的数据库行。在代表数据库条目的类的构造函数中创建 TCP 客户端并不是一个好主意。
相反,您可以使用ConcurrentDictionary<string, TcpConnection>线程安全的方式管理连接。
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |