Closed mojo-man closed 5 years ago
[1] [EXCEPTION - Visit Move] Cannot access a disposed object. ( at System.Reactive.DisposedObserver`1.OnNext(T value)
[1] at DotNetify.ReactiveProperty`1.OnNext(T value)
[1] at HME.Timer.Display.DisplayManager.ProcessVisitMessage(IMessage visitMsg) in C:\Content\Data\Dev\Janus-NewBaseline\DisplayServer\DisplayServer\DisplayManager.cs:line 262)
This seems to be happening since I updated to the latest version of dotnetify
The timer is trying to access a property of a view model instance that has been disposed (due the browser being refreshed). You should make sure the timer is also disposed as part of the view model dispose.
Which timer?
The timer that calls the view model property.
I am not using any timers - you are probably just seeing it in my namespace.
The "ProcessVisitMessage" is getting called from a different thread. That seems to be part of the problem.
I fire off a task in my constructor that receives messages via NetMQ.
Yes, when the VM Dispose is called, that thread needs to stop referencing the view model.
So - I need to kill that task from my OnDispose method?
One options is to emit a synchronization event to let that thread knows that the view model is being disposed, or to stop the thread altogether if that thread is only serving a single view model.
You mentioned that fire off the task in the constructor, so that task belongs to the view model instance, in which case, you can safely stop the task in the Dispose method.
That's what I am trying to do. Sending it a cancellation token.
Here is where I am starting my task (in the constructor):
_tokenSource = new CancellationTokenSource();
_token = _tokenSource.Token;
_receiverTask = Task.Factory.StartNew(() =>
{
// create a receiver
var _receiver = MessagingManager.GetMessageReceiver(_subscriptions);
Console.WriteLine("Created receiver on port {0}", _receiver.ListenEndPoint.Port);
// attach an event handler
_receiver.OnReceiveMessage += _receiver_OnReceiveMessage;
// start the receiver
_receiver.Start();
}, _token);
Task.WaitAll(_receiverTask);
and here is where I am overriding Dispose.
public override void Dispose()
{
_tokenSource.Cancel();
_receiverTask.Dispose();
base.Dispose();
}
Still getting exceptions
You probably have a race condition if you're still seeing the exception. Make sure the thread will no longer call the property after the Dispose completes. Anyhow, I don't think this is an issue with dotNetify library itself.
Gotcha - Thanks again for your help Dicky!!
Not quite there yet - but making positive progress. Also need to add in correlation id - as in your chat example.
When I refresh my browser window, I encounter a number of "Cannot access a disposed object" exceptions. Is there any synchronization that I need to do to prevent this?