0

I have a TcpListener which gets an endless stream of byte array. From that, I convert the byte() to MemoryStream and feed a PictureBox to display the images. That works fine. If I set the anchor points on the PictureBox to top/right/bottom/left which means the image will expand when the form expands and then I actually expand the form, I get the following error:

An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll

Additional information: Parameter is not valid.

Also,

The application is in break mode

Code

 ' Enter the listening loop.
        While True
            Dim client As TcpClient = Await server.AcceptTcpClientAsync()
            Dim stream As NetworkStream = client.GetStream
            Dim MS As New MemoryStream
            Await stream.CopyToAsync(MS)
            Await ViewImage(MS)
            client.Close()
        End While

View image function:

   Public Async Function ViewImage(ms As MemoryStream) As Task
        Try
            Dim myimage As Bitmap
            myimage = New Bitmap(ms)
            PictureBox1.Image = myimage
            PictureBox1.Refresh()
            myimage.Dispose()
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        End Try

    End Function

Please note that the exception is not caught within my code. Any ideas?

alwaysVBNET
  • 3,150
  • 8
  • 32
  • 65
  • Are you sure that _**the entire**_ image is received? Since TCP is a stream-based protocol the application layer has no knowledge of packets/the length of your data. You can either try serializing/deserializing the image over the stream using _Binary Serialization_, or see [**this answer of mine**](https://stackoverflow.com/a/35240061/3740093) which helps you split the data into packets of your own (known as _message framing_). – Visual Vincent Jul 11 '17 at 19:41
  • 1
    Oh wait, missed that you were closing the connection once the image has been received. Then it's not related to the data or packet size (though what I said above could be a good thing to consider in the future ;)). – Visual Vincent Jul 11 '17 at 19:47
  • 1
    Glad I could help! I don't know how much you know about reference/value types, but I added a basic example to my answer for those who don't know. – Visual Vincent Jul 11 '17 at 20:13

1 Answers1

2

The issue is most likely related to the fact that you dispose myimage at the end of your ViewImage() method.

This:

PictureBox1.Image = myimage
...
myimage.Dispose()

makes myimage and PictureBox1.Image point to the same Bitmap object. Bitmaps are reference types (classes) which means that you're just passing their reference pointer around when you assign it to different variables.

Thus when you dispose myimage you are disposing the same image that is being shown in the PictureBox, which could cause that error of yours when GDI+ tries to redraw a stretched version of it (as a matter of fact not even the original image should be displayed once you've disposed it).

For more info see: Value Types and Reference Types - Microsoft Docs.


Basic example of how Reference Types and Value Types work

Reference types:

Dim A As New Bitmap("image.bmp")

Dim B As Bitmap = A 'Points to A.
PictureBox1.Image = A 'Points to A.
PictureBox2.Image = B 'Still points to A.

'Calling Dispose() on any of the above will result in none of them having an image since you will ultimately dispose bitmap A.

Value types:

Dim A As Integer = 3

Dim B As Integer = A 'Copy of A.
Dim C As Integer = B 'Copy of B.

C = 4 'Results in A = 3, B = 3, C = 4.
Visual Vincent
  • 18,045
  • 5
  • 28
  • 75