我有一个使用 .NET Framework 4.6.1 实现的控制台应用程序,如此处所述。
.NET框架4.6.1 Microsoft.AspNet.SignalR 版本 2.4.2 StackExchange.Redis 版本 2.1.58
我们使用 StackExchangeRedis Resolver 并且已经设置了 DefaultMessageBufferSize = 32。 当我断开并重新连接设备时,我会体验到内存的增加。
Startup.cs
public void Configuration(IAppBuilder appBuilder)
{
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(connectionTimeout);
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(disconnectTimeout);
GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(keepAlive);
GlobalHost.Configuration.DefaultMessageBufferSize = defaultMessageBufferSize;
appBuilder.MapSignalR($"/{GetAppSettingValue("SignalRAddress")}", new HubConfiguration()
{
EnableDetailedErrors = TraceMode,
EnableJavaScriptProxies = true,
EnableJSONP = true,
Resolver = GlobalHost.DependencyResolver.UseStackExchangeRedis(
new RedisScaleoutConfiguration(SignalRedisConnection, GetAppSettingValue("AppName"))
)
});
appBuilder.UseNinjectMiddleware(CreateKernel);
}
private static IKernel CreateKernel()
{
Kernel.Bind<IXXX>().To<XXX>().InSingletonScope();
...
return Kernel;
}
程序.cs
class Program
{
static void Main(string[] args)
{
HostFactory.Run(x =>
{
x.Service<SignalRService>(s =>
{
string servicename = "Web Socket Service";
x.SetServiceName(servicename);
x.SetDescription("...");
x.SetDisplayName(servicename);
x.SetInstanceName(servicename);
s.ConstructUsing(n => new SignalRService());
s.WhenStarted((service, hostControl) => service.Start(hostControl));
s.WhenStopped((service, hostControl) => service.Stop(hostControl));
});
x.EnableShutdown();
x.RunAsLocalSystem();
x.UseAssemblyInfoForServiceInfo();
x.SetStartTimeout(TimeSpan.FromMinutes(2));
x.SetStopTimeout(TimeSpan.FromMinutes(2));
x.DependsOnEventLog();
});
}
}
internal class SignalRService : ServiceControl
{
public SignalRService()
{
Task.Run(() =>
{
WebApp.Start<Startup>(Address);
...
}).Wait();
_timer = new Timer(MyTimerAsync, null, 0, Convert.ToInt32(Startup.LostDeviceTimer.TotalMilliseconds));
}
private async void MyTimerAsync(object stateInfo)
{
var broadcaster = BroadcastManager.Instance;
...
}
}
BrokerHubManager.cs
public class BrokerHubManager : Hub
{
private readonly BroadcastManager _broadcaster;
public BrokerHubManager() : this(BroadcastManager.Instance)
{
...
}
public BrokerHubManager(BroadcastManager broadCaster)
{
_broadcaster = broadCaster;
}
}
BroadcastManager.cs
public class BroadcastManager
{
private static readonly Lazy<BroadcastManager> _instance = new Lazy<BroadcastManager>(
() => new BroadcastManager(GlobalHost.ConnectionManager.GetHubContext<BrokerHubManager>()));
private BroadcastManager(IHubContext context)
{
...
}
public static BroadcastManager Instance
{
get { return _instance.Value; }
}
}
我尝试实现如此处所示的处置,但我仍然收到错误。
问题在于 BroadcastManager._instance 没有按照第二张图片所示进行处置。 你有什么建议吗?
按照 Guru Stron 的建议,我修改了代码如下,但内存泄漏问题仍然存在。
Startup.cs
public void Configuration(IAppBuilder appBuilder)
{
...
appBuilder.UseNinjectMiddleware(CreateKernel);
}
private static IKernel CreateKernel()
{
Kernel.Bind<IBroadcastManager>().To<BroadcastManager>().InSingletonScope();
Kernel.Bind<IHubContext>().ToMethod(context =>
GlobalHost.ConnectionManager.GetHubContext<BrokerHubManager>()
).WhenInjectedInto<IBroadcastManager>();
...
return Kernel;
}
程序.cs
class Program
{
static void Main(string[] args)
{
...
}
}
internal class SignalRService : ServiceControl
{
private IBroadcastManager _broadcaster;
public SignalRService()
{
Task.Run(() =>
{
WebApp.Start<Startup>(Address);
_broadcaster = Startup.Kernel.Get<IBroadcastManager>();
...
}).Wait();
_timer = new Timer(MyTimerAsync, null, 0, Convert.ToInt32(Startup.LostDeviceTimer.TotalMilliseconds));
}
private async void MyTimerAsync(object stateInfo)
{
_broadcaster.XXX();
...
}
}
BrokerHubManager.cs
public class BrokerHubManager : Hub
{
public BrokerHubManager()
{
...
}
}
BroadcastManager.cs
public class BroadcastManager : IBroadcastManager
{
private IHubContext _context;
private BroadcastManager(IHubContext context)
{
_context = context;
}
}