Unhandled "cannot access a disposed object" exception
This seems to have happened seconds after the client handled a disconnect from the server. The client had been running for about 2 hours already
I didn't delve in the source just yet but it looks like this may be solved just by checking if the timer is disposed
Here are the logs:
Cannot access a disposed object. at System.Threading.TimerQueueTimer.Change(UInt32 dueTime, UInt32 period) at WebSocket4Net.WebSocket.ClearTimer() at WebSocket4Net.WebSocket.FireClosed() at WebSocket4Net.WebSocket.OnClosed() at SuperSocket.ClientEngine.ClientSession.OnClosed() at SuperSocket.ClientEngine.AsyncTcpSession.ProcessReceive(SocketAsyncEventArgs e) at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags) at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Faced similar issue. Though I see a fix already applied for handling a disposed timer here - a4bcac3, using v0.15.2
Catched same exception in v0.15.2.11
me to System.ObjectDisposedException: Cannot access a disposed object. at System.Threading.TimerQueueTimer.Change(UInt32 dueTime, UInt32 period) at System.Threading.Timer.Change(Int32 dueTime, Int32 period) at WebSocket4Net.WebSocket.ClearTimer() at WebSocket4Net.WebSocket.FireClosed() at WebSocket4Net.WebSocket.OnClosed() at SuperSocket.ClientEngine.AuthenticatedStreamTcpSession.SendInternal(PosList`1 items) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.Security._SslStream.StartWriting(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security._SslStream.WriteCallback(IAsyncResult transportResult) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.ContextAwareResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Can also confirm.
Interlocked.CompareExchange was changed to lock statement at 1ab610a. I think this change is not equivalent.
In my case, this bug happens when both client and server close connection. I suppose that two threads may enter that lock section: my code and data receiving thread. When my code calls Close first, then ping timer is replaced by closing handshake timer. But at the same time receiving thread may also call ClearTimer, so both will simultaneously enter lock. Receiving thread code will check m_WebSocketTimer that will not be null, then dispose old local timer copy that have already been disposed by my code.
Same error here as well
Cannot access a disposed object. at System.Threading.TimerQueueTimer.Change(UInt32 dueTime, UInt32 period) at System.Threading.Timer.Change(Int32 dueTime, Int32 period) at WebSocket4Net.WebSocket.ClearTimer() at WebSocket4Net.WebSocket.FireClosed() at WebSocket4Net.WebSocket.OnClosed() at SuperSocket.ClientEngine.AuthenticatedStreamTcpSession.OnDataRead(IAsyncResult result) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.AsyncProtocolRequest.CompleteWithError(Exception e) at System.Net.Security._SslStream.ReadHeaderCallback(AsyncProtocolRequest asyncRequest) at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result) at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes) at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.ContextAwareResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
We are hitting this routinely during stress tests.
Could it be caused by the double-checked locking on a non-volatile field used inside ClearTimer() here:
https://github.com/kerryjiang/WebSocket4Net/blob/v0.15/WebSocket4Net/WebSocket.cs#L710