zeromq / netmq

A 100% native C# implementation of ZeroMQ for .NET
Other
2.94k stars 742 forks source link

invoke SendMoreFrame occurred error while concurrent testing #1005

Open liuyl1992 opened 2 years ago

liuyl1992 commented 2 years ago

Environment

NetMQ Version:    4.0.1.8
Operating System: win10
.NET Version:     .NET6

Expected behaviour

An error occurred while executing concurrent testing. invoke this is _publisherSocket.SendMoreFrame("A:b") .SendFrame(DateTimeOffset.Now.ToString());

An unhandled exception has occurred while executing the request: System.IndexOutOfRangeException: Index was outside the bounds of the array.

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request. System.IndexOutOfRangeException: Index was outside the bounds of the array. at NetMQ.Core.Utils.YQueue1.Push(T& val) at NetMQ.Core.YPipe1.Write(T& value, Boolean incomplete) at NetMQ.Core.Pipe.Write(Msg& msg) at NetMQ.Core.Patterns.Utils.Distribution.Write(Pipe pipe, Msg& msg) at NetMQ.Core.Patterns.Utils.Distribution.Distribute(Msg& msg) at NetMQ.Core.Patterns.Utils.Distribution.SendToMatching(Msg& msg) at NetMQ.Core.Patterns.XPub.XSend(Msg& msg) at NetMQ.Core.SocketBase.TrySend(Msg& msg, TimeSpan timeout, Boolean more) at NetMQ.NetMQSocket.TrySend(Msg& msg, TimeSpan timeout, Boolean more) at NetMQ.OutgoingSocketExtensions.Send(IOutgoingSocket socket, Msg& msg, Boolean more) at NetMQ.OutgoingSocketExtensions.SendFrame(IOutgoingSocket socket, String message, Boolean more) at NetMQ.OutgoingSocketExtensions.SendMoreFrame(IOutgoingSocket socket, String message) at XXX.Plugin.Tdengine.ZeroMQController.PublisherSocket() in ZeroMQ\Controller\ZeroMQController.cs:line 55

Actual behaviour

image image

image

image

project code github address:https://github.com/LeonKou/NetPro/blob/dev_6.0/src/sample/XXX.Plugin.ZeroMQ/Controller/ZeroMQController.cs

liuyl1992 commented 2 years ago

Runs well without concurrent testing

b2yq commented 2 years ago

Are you using socket from multiple threads? I can see that you have registered it as a singleton and used it in web handler. Web app requests by default runs on thread-pull, its got something around 30 threads. You can call socket only by one thread. The easiest way to achieve that is to use actor-pattern. Create object with thread and socket inside. Entrance into that object can be a NetMq queue and output can be a socket. Inside thread you can use Poller to listen on input and when new message arrive put it into the socket.