1iveowl / WebsocketClientLite.PCL

Websocket client lite
MIT License
38 stars 14 forks source link

The BeginWrite method cannot be called when another write operation is pending #32

Closed Workshop2 closed 7 years ago

Workshop2 commented 7 years ago

I think I posted this in the wrong repo, sorry - https://github.com/1iveowl/SocketLite.PCL/issues/5

Hello,

I am getting the following error when I run my integration test. Each test creates a new connection and closes it and I get the following intermittently:

(SetUp and TearDown)

Just had a quick read of the article you found. Via the tests everything is awaited on the same thread so wouldn't have thought that would cause an issue.

I am seeing it occur mainly on the TearDown. I am doing both a Dispose and a CloseAsync but looking at your library the Dispose doesn't do anything.

SetUp : System.AggregateException : One or more errors occurred.
  ----> System.NotSupportedException : The BeginWrite method cannot be called when another write operation is pending.
TearDown : System.NullReferenceException : Object reference not set to an instance of an object.
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at SlackConnector.Tests.Integration.IntegrationTest.SetUp() in C:\code\slackconnector\src\SlackConnector.Tests.Integration\IntegrationTest.cs:line 19
--NotSupportedException
   at System.Net.Security._SslStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback asyncCallback, Object asyncState)
   at System.IO.Stream.<>c.<BeginEndWriteAsync>b__53_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod)
   at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count)
   at WebsocketClientLite.PCL.Service.WebsocketSenderService.<SendFrameAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at WebsocketClientLite.PCL.Service.WebsocketSenderService.<ComposeFrameAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at WebsocketClientLite.PCL.Service.WebsocketSenderService.<SendTextAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at WebsocketClientLite.PCL.MessageWebSocketRx.<SendTextAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at SlackConnector.Connections.Sockets.WebSocketClientLite.<SendMessage>d__8.MoveNext() in C:\code\slackconnector\src\SlackConnector\Connections\Sockets\WebSocketClientLite.cs:line 47
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at SlackConnector.SlackConnection.<Ping>d__54.MoveNext() in C:\code\slackconnector\src\SlackConnector\SlackConnection.cs:line 258
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at SlackConnector.Connections.Monitoring.PingPongMonitor.<StartMonitor>d__6.MoveNext() in C:\code\slackconnector\src\SlackConnector\Connections\Monitoring\PingPongMonitor.cs:line 33
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at SlackConnector.SlackConnection.<Initialise>d__36.MoveNext() in C:\code\slackconnector\src\SlackConnector\SlackConnection.cs:line 69
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at SlackConnector.SlackConnectionFactory.<Create>d__0.MoveNext() in C:\code\slackconnector\src\SlackConnector\SlackConnectionFactory.cs:line 14
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SlackConnector.SlackConnector.<Connect>d__5.MoveNext() in C:\code\slackconnector\src\SlackConnector\SlackConnector.cs:line 58
--TearDown
   at SlackConnector.Tests.Integration.IntegrationTest.TearDown() in C:\code\slackconnector\src\SlackConnector.Tests.Integration\IntegrationTest.cs:line 25
1iveowl commented 7 years ago

Could you try v3.7.3-beta1?

I just uploaded it to NuGet.

Not sure that it helps, but it does some more clean-up now when disposed.

1iveowl commented 7 years ago

In v3.7.3-beta2 I introduce a ConcurrencyQueue on the send and a lock that prevent that anything can be written before the previous write has completed.

Let me know if this does the job.

Workshop2 commented 7 years ago

Wow, never known such a turn-around. Seems to work great 👍

1iveowl commented 7 years ago

Great. Thanks

Just for curiosity. Did beta1 or beta2 solve the issue?

Workshop2 commented 7 years ago

@1iveowl beta2

1iveowl commented 7 years ago

Thank you. Beta2 was what I thought too.

I've release v3.7.3. Happy coding...