Write a CircularStream for wcf

Source: Internet
Author: User

After providing the streaming method, wcf has always had a small problem and cannot find a suitable stream carrier. If you can use the file stream or something to return values, it would be better, but in more cases, you need to return a stream, but the Stream does not have a real carrier like a file, and sometimes the stream is large (if it is small, you do not need to use the streaming method ), at this time, it seems a little troublesome.

First of all, I don't like using MemoryStream because it actually occupies so much memory. In the case of a large amount of data, the power of the wcf streaming method will be greatly reduced. Of course, you can also use the file to return the file stream to bypass this problem, or use other ready-made streams.

However, I prefer to use logic similar to Circular Buffer to process this stream, which can occupy a small amount of memory to output a large volume of streams, the advantage of the streaming mode of wcf is maximized.

However, I checked several implementations of Circlar Buffer on the Internet, but I don't feel very satisfied... However, you can create one by yourself:

CircularStream public class CircularStream
: Stream
{

# Region Fields
Private const int DefaultCapacity = 0x10000;
Private readonly object SyncRoot = new object ();
Private bool m_closed;
Private readonly byte [] m_buffer;
Private int m_read;
Private int m_write;
# Endregion

# Region Ctors

Public CircularStream (int capacity)
{
M_buffer = new byte [capacity];
}

Public CircularStream (Action <Stream> action)
: This (defacapcapacity)
{
ThreadPool. QueueUserWorkItem (_ =>
{
Try
{
Action (this );
}
Finally
{
This. Dispose ();
}
});
}

# Endregion

# Region Overrides

Public override bool CanRead
{
Get {return true ;}
}

Public override bool CanSeek
{
Get {return false ;}
}

Public override bool CanWrite
{
Get {return true ;}
}

Public override void Flush (){}

Public override long Length
{
Get {throw new NotSupportedException ();}
}

Public override long Position
{
Get {throw new NotSupportedException ();}
Set {throw new NotSupportedException ();}
}

Public override long Seek (long offset, SeekOrigin origin)
{
Throw new NotSupportedException ();
}

Public override void SetLength (long value)
{
Throw new NotSupportedException ();
}

Protected override void Dispose (bool disposing)
{
Lock (SyncRoot)
{
M_closed = true;
Monitor. Pulse (SyncRoot );
}
Base. Dispose (disposing );
}

Public override int Read (byte [] buffer, int offset, int count)
{
Lock (SyncRoot)
{
While (m_read = m_write) // empty
If (m_closed)
Return 0;
Else
Monitor. Wait (SyncRoot, 100, true );
Int c;
If (m_write> m_read)
C = m_write-m_read;
Else
C = m_buffer.Length-m_read;
Monitor. Pulse (SyncRoot );
If (c> count)
{
Buffer. BlockCopy (m_buffer, m_read, buffer, offset, count );
M_read + = count;
Return count;
}
Else
{
Buffer. BlockCopy (m_buffer, m_read, buffer, offset, c );
M_read = (m_read + c) % m_buffer.Length;
Return c;
}
}
}

Public override void Write (byte [] buffer, int offset, int count)
{
Lock (SyncRoot)
{
If (m_closed)
Throw new ObjectDisposedException ("CircleBufferStream ");
While (count> 0)
{
While (m_write + 1) % m_buffer.Length = m_read) // full
Monitor. Wait (SyncRoot, 100, true );
If (m_read> m_write)
{
Int c = Math. Min (m_read-m_write-1, count );
Buffer. BlockCopy (buffer, offset, m_buffer, m_write, c );
M_write + = c;
Count-= c;
Offset + = c;
}
Else
{
Int c = m_buffer.Length-m_write;
If (m_read = 0)
-- C;
If (c> count)
{
Buffer. BlockCopy (buffer, offset, m_buffer, m_write, count );
M_write + = count;
Count = 0;
}
Else
{
Buffer. BlockCopy (buffer, offset, m_buffer, m_write, c );
M_write = (m_write + c) % m_buffer.Length;
Count-= c;
Offset + = c;
}
}
Monitor. Pulse (SyncRoot );
}
}
}

# Endregion

# Region Properties

Public int Capacity {get {return m_buffer.Length ;}}

# Endregion

}

Add related contracts and implementations:

Contract [ServiceContract]
Public interface IService1
{
[OperationContract]
Stream GetStream (int value );
} Implement public class Service1: IService1
{
Public Stream GetStream (int value)
{
Return new CircularStream (s =>
New XStreamingElement ("root ",
From I in Enumerable. Range (1, value)
Select new XElement ("item ",
New XAttribute ("id", I). Save (s ));
}
}

And the called services and clients:

Service and client static class Program
{
Static void Main (string [] args)
{
Var host = new ServiceHost (typeof (Service1 ));
Host. Open ();
Var binding = new BasicHttpBinding ();
Binding. TransferMode = TransferMode. StreamedResponse;
Binding. maxcompute edmessagesize = int. MaxValue;
// If you don't think you are addicted, you can turn on the loop.
// For (int I = 0; I <100; I ++)
//{
New Uri ("http: // localhost: 12123/"). InvokeWcfClient <IService1> (binding, c =>
{
Var stream = c. GetStream (10000 );
String line;
Using (var r = new StreamReader (stream ))
While (null! = (Line = r. ReadLine ()))
Console. WriteLine (line );
});
//}
Host. Close ();
}

Public static void InvokeWcfClient <TChannel> (
This Uri uri, Binding binding, Action <TChannel> action)
Where TChannel: class
{
TChannel client = ChannelFactory <TChannel>. CreateChannel (
Binding, new EndpointAddress (uri ));
Var co = (ICommunicationObject) client;
Try
{
Co. Open ();
Action (client );
}
Finally
{
If (co. State = CommunicationState. Faulted)
Co. Abort ();
Else
Co. Close ();
}
}
}

In this way, you can run it perfectly.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.