Results 1 to 5 of 5

Thread: IceSL 0.3.3: MemoryStream issue

  1. #1
    kwaclaw is offline Registered User
    Name: Karl Waclawek
    Organization: Personal
    Project: Whiteboard application
    Join Date
    Sep 2004
    Location
    Oshawa, Canada
    Posts
    159

    IceSL 0.3.3: MemoryStream issue

    I recently encountered this exception in Ice for Silverlight:
    (not asking for support, just reporting it)

    Error: Unhandled Error in Silverlight 2 Application Memory stream is not expandable. at System.IO.__Error.MemoryStreamNotExpandable()
    at System.IO.MemoryStream.set_Capacity(Int32 value)
    at System.IO.MemoryStream.EnsureCapacity(Int32 value)
    at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
    at IceInternal.IceConnection.receiveCompleted(Object sender, SocketAsyncEventArgs e)
    at System.Net.Sockets.SocketAsyncEventArgs.OnComplete d(SocketAsyncEventArgs e)
    at System.Net.Sockets.SocketAsyncEventArgs.FinishOper ationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
    at System.Net.Sockets.SocketAsyncEventArgs.Completion PortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
    at System.Threading._IOCompletionCallback.PerformIOCo mpletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

    I am not sure how I can reliably reproduce it, but as far as I can tell, the ReadCallback in IceConnection.cs class instantiates a non-resizable stream which then throws this exception when the need for expansion arises.

    Karl
    Karl Waclawek

  2. #2
    kwaclaw is offline Registered User
    Name: Karl Waclawek
    Organization: Personal
    Project: Whiteboard application
    Join Date
    Sep 2004
    Location
    Oshawa, Canada
    Posts
    159
    Quote Originally Posted by kwaclaw View Post
    I am not sure how I can reliably reproduce it, but as far as I can tell, the ReadCallback in IceConnection.cs class instantiates a non-resizable stream which then throws this exception when the need for expansion arises.

    Karl
    The issues seeems to happen whenever ReadCallback.prepareWrite() enter the "else" branche of its main "if" statement.

    The code there looks like:
    Code:
      int length = (int) (_stream.Length - _replySize);
      Byte[] buff = new Byte[length];
      _stream.Position = _replySize;
      _stream.Read(buff, 0, length);
      _stream = new MemoryStream(buff);
      _replySize = 0;
      _stream.Position = length;
    This memorystream is not resizable. It can be made so by changing the code:
    Code:
      int length = (int) (_stream.Length - _replySize);
      MemoryStream ms = new MemoryStream(length);
      byte[] buff = ms.GetBuffer();
      _stream.Position = _replySize;
      _stream.Read(buff, 0, length);
      ms.SetLength(length);
      ms.Position = length;
      _stream = ms;
      _replySize = 0;
    However, if this is the solution, it is not complete, as I now get an Ice.BadMagicException:

    Error: Unhandled Error in Silverlight 2 Application Exception of type 'Ice.BadMagicException' was thrown. at Ice.ObjectPrxHelperBase.handleExceptionWrapper__(L ocalExceptionWrapper ex)
    at KdSoftIce.Services.WhiteboardService.WhiteboardSes sionPrxHelper.AddPoints(Int32 clientId, StylusPoint[] points, Dictionary`2 context__, Boolean explicitContext__)
    at KdSoftIce.Services.WhiteboardService.WhiteboardSes sionPrxHelper.AddPoints(Int32 clientId, StylusPoint[] points)
    at WhiteBoardSL.Page.AddPointsTask.DoExecute()
    Source File: http://localhost:4404/WhiteBoardSLTe...s-citxp-kwacla
    Line: 0

    Karl
    Karl Waclawek

  3. #3
    kwaclaw is offline Registered User
    Name: Karl Waclawek
    Organization: Personal
    Project: Whiteboard application
    Join Date
    Sep 2004
    Location
    Oshawa, Canada
    Posts
    159
    Quote Originally Posted by kwaclaw View Post
    However, if this is the solution, it is not complete, as I now get an Ice.BadMagicException:
    Seems my fix was not good - apparently MemoryStream.SetLength clears the stream. Rearranging the order seems to work:
    Code:
      int length = (int) (_stream.Length - _replySize);
      MemoryStream ms = new MemoryStream();
      ms.SetLength(length);
      byte[] buff = ms.GetBuffer();
      _stream.Position = _replySize;
      _stream.Read(buff, 0, length);
      ms.Position = length;
      _stream = ms;
      _replySize = 0;
    So far I could not re-create the error, so the situation seems improved at least.

    Karl
    Karl Waclawek

  4. #4
    xdm's Avatar
    xdm
    xdm is offline ZeroC Staff
    Name: Jose Gutierrez de la Concha
    Organization: ZeroC, Inc.
    Project: Ice Developer
    Join Date
    Sep 2003
    Location
    La Coruña, Spain
    Posts
    588
    Hi Karl,

    Thanks for the bug report and sorry for the late replay, i'm glad you already found a solution for the issue, as you say the problem is that MemoryStream that are not create with the default constructor cannot be expandable.

    I have made a fix similar to yours but not require to call SetLength

    Code:
    public void prepareWrite()
        {
            if(_stream == null || _replySize == _stream.Length)
            {
                _replySize = 0;
                _stream = new MemoryStream();
                _stream.Position = 0;
            }
            else
            {
                int length = (int) (_stream.Length - _replySize);
                Byte[] buff = new Byte[length];
                _stream.Position = _replySize;
                _stream.Read(buff, 0, length);
                _stream = new MemoryStream();
                _stream.Write(buff, 0, length);
                _replySize = 0;
            }
        }
    Cheers,
    José

  5. #5
    kwaclaw is offline Registered User
    Name: Karl Waclawek
    Organization: Personal
    Project: Whiteboard application
    Join Date
    Sep 2004
    Location
    Oshawa, Canada
    Posts
    159
    Quote Originally Posted by xdm View Post
    Hi Karl,

    I have made a fix similar to yours but not require to call SetLength

    Code:
        int length = (int) (_stream.Length - _replySize);
        Byte[] buff = new Byte[length];
        _stream.Position = _replySize;
        _stream.Read(buff, 0, length);
        _stream = new MemoryStream();
        _stream.Write(buff, 0, length);
        _replySize = 0;
    That should work as well, only it requires more processing.
    This code will allocate a buffer twice (the second time as side effect of writing to the new stream), and fill it twice (the second time when writing to the new stream).

    I tried to allocate and fill the buffer only once:
    Code:
        int length = (int) (_stream.Length - _replySize);
        MemoryStream ms = new MemoryStream();
        ms.SetLength(length);            // allocates buffer inside new stream
        byte[] buff = ms.GetBuffer();    // get reference to new buffer
        _stream.Position = _replySize;
        _stream.Read(buff, 0, length);   // fill the new stream's buffer
        ms.Position = length;            // fix up the position
        _stream = ms;
        _replySize = 0;
    Karl
    Karl Waclawek

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. IceSL and Silverlight 4
    By kwaclaw in forum Comments
    Replies: 2
    Last Post: 05-12-2010, 10:38 PM
  2. IceSL 0.3.2: oneway outgoing calls not supported?
    By kwaclaw in forum Bug Reports
    Replies: 1
    Last Post: 10-23-2008, 12:59 PM
  3. IceSL 0.3.2: ArgumentException in IceConnection.cs
    By kwaclaw in forum Bug Reports
    Replies: 0
    Last Post: 10-20-2008, 05:41 PM
  4. IceSL 0.3.2 - generateUUID()
    By kwaclaw in forum Bug Reports
    Replies: 1
    Last Post: 10-20-2008, 07:40 AM
  5. Connections Issue #9
    By marc in forum Announcements
    Replies: 0
    Last Post: 12-06-2005, 12:21 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •