Я в основном пытаюсь выполнить какую-то работу с базой данных, если пользователь был отключен от signalR более чем на 10 минут. Я поместил таймер в OnDisconnectedAsync Хаба (). Проблема, с которой я сталкиваюсь - это ObjectDisposedException для вещей, которые мне нужны для доступа к базе данных. У меня возникают те же проблемы, когда я обхожу таймер и пытаюсь сделать вызовы непосредственно в OnDisconnectedAsync (). Я предполагаю, что все было разрушено к тому времени, когда я делаю это в OnDisconnectedAsync ().
Я пробовал все, что я могу найти в течение нескольких дней, но, похоже, ничего не работает. Как правильно решить эту проблему?
public class RangeHub : Hub
{
private readonly IHubContext<RangeHub> _hubContext;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IDashboardService _service;
private readonly ApplicationDbContext _context;
private readonly ISubscriptionService _subscription;
private readonly HOptions _hOptions;
//private Timer disconnectTimer = new Timer();
private CustomTimer disconnectTimer;
private string UserId
{
get
{
//return User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier).Value;
return Context.UserIdentifier;
}
}
public RangeHub(IHubContext<RangeHub> hubContext, UserManager<ApplicationUser> userManager, IDashboardService service, ApplicationDbContext context,
ISubscriptionService subscription, IOptionsMonitor<HOptions> hOptions)
{
_hubContext = hubContext;
_context = context;
_userManager = userManager;
_service = service;
_subscription = subscription;
_hOptions = hOptions.CurrentValue;
disconnectTimer = new CustomTimer
{
Interval = 30000,
AutoReset = false
};
disconnectTimer.Elapsed += DisconnectTimedEvent;
//disconnectTimer.Elapsed += (sender, e) => DisconnectTimedEvent(sender, e, UserId);
//disconnectTimer.Interval = 30000;//120000;
//disconnectTimer.AutoReset = false;
}
public override Task OnConnectedAsync()
{
Log.Information("OnConnectedAsync: CONNECT TO CLIENT");
System.Diagnostics.Debug.WriteLine("OnConnectedAsync: CONNECT TO CLIENT");
//If timer was running, stop timer/reset
if(disconnectTimer.Enabled)
{
//reset timer
disconnectTimer.Stop();
}
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
//TODO: This is firing off when the dashboard is left, need to fix
Log.Information("OnDisconnectedAsync: DISCONNECTED FROM CLIENT");
System.Diagnostics.Debug.WriteLine("OnDisconnectedAsync: DISCONNECTED FROM CLIENT");
_service.StopActiveEnvironment(UserId);
//_hubContext.Clients.
//TODO: place logic here to stop environment and stop user's time
disconnectTimer.userId = UserId;
disconnectTimer.dashService = _service;
disconnectTimer.dBContext = _context;
//disconnectTimer.Start();
//*is this for a single user? will this effect all users at once?
return base.OnDisconnectedAsync(exception);
}
public void DisconnectTimedEvent(object sender, ElapsedEventArgs e)//, IDashboardService dashService)
{
//Shut down the range
Log.Information("DEBUG Timer");
Log.Information("UserId: " + ((CustomTimer)sender).userId);
Log.Information("Shutting down environment due to signalR disconnection timer.");
//Van - 9-28-2019: Not using await here. This should be the last thing done before the instance of this class is destroyed.
// Using await takes too long and the Hub object is already destroyed before its finished.
//_service.StopActiveEnvironment(((CustomTimer)sender).userId);
//Task.Run(async () => await _service.StopActiveEnvironment("051735c4-fa6d-4d90-9f76-b540aaa110bc"));
//Task.Run(async () => await _service.StopActiveEnvironment("051735c4-fa6d-4d90-9f76-b540aaa110bc")).WaitAndUnwrapException();
try
{
var func = ((CustomTimer)sender).dashService.StopActiveEnvironment(((CustomTimer)sender).userId);
func.WaitAndUnwrapException();
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
}
class CustomTimer : Timer
{
public string userId;
public IDashboardService dashService;
public ApplicationDbContext dBContext;
}