zeromq / clrzmq4

ZeroMQ C# namespace (.NET and mono, Windows, Linux and MacOSX, x86 and amd64)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug in public virtual bool Send(IEnumerable<ZFrame> frames, ZSocketFlags flags, out ZError error)

AntiTenzor opened this issue · comments

This function throws an exception in .NET Framework 4.8 if I call it with a fixed-size array as a first argument.

Here is a full listing to reproduce the issue:

`
using System;

using ZeroMQ;

namespace BugClrzmq4
{
internal class Program
{
public static void Main(string[] args)
{
using (ZContext clrZmqContext = ZContext.Current)
using(ZSocket pub = new ZSocket(ZSocketType.PUB))
{
pub.Bind("inproc://pub");

            ZFrame z1 = new ZFrame("line1");
            ZFrame z2 = new ZFrame("line2");

            /*

This line throws an exception:
Unhandled Exception: System.NotSupportedException: Collection was of a fixed size.
at System.SZArrayHelper.Remove[T](T value)
at ZeroMQ.ZSocket.SendFrames(IEnumerable1 frames, Int32& sent, ZSocketFlags flags, ZError& error) in w:\git\clrzmq4\ZSocket.cs:line 720 at ZeroMQ.ZSocket.SendFrames(IEnumerable1 frames, ZSocketFlags flags, ZError& error) in w:\git\clrzmq4\ZSocket.cs:line 682
at BugClrzmq4.Program.Main(String[] args) in W:\Source\CS\BugClrzmq4\BugClrzmq4\BugClrzmq4\Program.cs:line 35
*/
pub.Send(new ZFrame[] { z1, z2 }, ZSocketFlags.DontWait, out ZError error);

            /*

ZSocket.cs lines 719-221:
if (framesIsList)
{
((IList)frames).Remove(frame);
}
*/

            /*

This is because fixed-sized array new ZFrame[] { z1, z2 } IS IList,
but you can NOT remove elements from it (even after cast).
*/
Console.WriteLine("error: {0}", error);

            /*

Actually I do not understand why do you even bother to remove elements?
AFAIK, for many collections (such as List) Remove is relatively expensive operation.
*/
}
}
}
}
`

Nobody is interested?

To be frank, the formatting of your post does not invite readers.

Anyways, I agree it is a bad idea to remove the ZFrames from the message to be sent. Especially when it is a List.
Sending ZMessages has caused us great performance problems, because ZMessage is implemented using effectively an ArrayList, meaning the send function suddenly has quadratic complexity.
Sending a 10_000 ZFrame ZMessage took 4,2s. Optimizing this by doing all the things the wrapper functions would have done (minus the remove operation) I got that down to 13ms.