Skip to content

C# large streams do not permit async event handlers #186

Open
@Niproblema

Description

@Niproblema

I have figured that sending large streams just does not work when using async.
For example,

Client side:

                    case "sendlargeasync":
                        Stream stream = GetStream(2000);
                        success = client.SendAsync(stream.Length, stream).Result;
                        Console.WriteLine(success);
                        break;

where GetStream() generates some random large stream. E.g.

        private static MemoryStream GetStream(long mb)
        {
            Random rng = new Random();
            long size = mb * 1024 * 1024;
            if (size < int.MaxValue - 60)
            {

                byte[] streamContents = new byte[mb * 1024 * 1024];
                rng.NextBytes(streamContents);
                MemoryStream memoryStream = manager.GetStream(streamContents);

                memoryStream.Position = 0;
                return memoryStream;
            }
            else
            {
                MemoryStream memoryStream = manager.GetStream();
                memoryStream.WriteByte((byte)rng.Next(256));
                memoryStream.Seek(mb * 1024 * 1024, SeekOrigin.Begin);
                memoryStream.WriteByte((byte)rng.Next(256));
                memoryStream.Position = 0;
                return memoryStream;
            }
        }

Server side:

        private static void StreamReceived(object sender, StreamReceivedEventArgs args)
        {
            try
            {
                MemoryStream ss = new MemoryStream();
                args.DataStream.CopyTo(ss);

This works perfectly, but I require non blocking approach...

        private static async void StreamReceived(object sender, StreamReceivedEventArgs args)
        {
            try
            {
                await Task.Delay(100);
                // At this point Environment.CurrentManagedThreadId is different to the one that the library invoked the event handler with.

                MemoryStream ss = new MemoryStream();
                args.DataStream.CopyTo(ss);   
           ....

In this example deadlock occurs and the copyTo() never returns. Meanwhile the client receives successful sendAsync and returns. This is true only when stream is over MaxProxiedStreamSize . (See #168 (reply in thread)_)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions