Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhandled "cannot access a disposed object" exception #141

Open
LolliDepp opened this issue Nov 7, 2018 · 6 comments
Open

Unhandled "cannot access a disposed object" exception #141

LolliDepp opened this issue Nov 7, 2018 · 6 comments

Comments

@LolliDepp
Copy link

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)

@aady501
Copy link

aady501 commented Nov 27, 2019

Faced similar issue. Though I see a fix already applied for handling a disposed timer here - a4bcac3,
using v0.15.2

@Polimat
Copy link

Polimat commented Jan 16, 2020

Catched same exception in v0.15.2.11

@NektoDron
Copy link

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)

@aubiyko
Copy link

aubiyko commented Jun 16, 2020

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.

@MarkoPielic
Copy link

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)

@julbra
Copy link

julbra commented Jul 5, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants