Ðаn*_*Ðаn 5 .net rest httpwebrequest .net-4.5 dotnet-httpclient
使用 HttpWebRequest,我可以调用 XDocument.Save()直接写入请求流:
XDocument doc = ...;
var request = (HttpWebRequest)WebCreate.Create(uri);
request.method = "POST";
Stream requestStream = request.GetRequestStream();
doc.Save(requestStream);
Run Code Online (Sandbox Code Playgroud)
是否可以用 做同样的事情HttpClient?直接的方法是
XDocument doc = ...;
Stream stream = new MemoryStream();
doc.Save(stream);
var content = new System.Net.Http.StreamContent(stream);
var client = new HttpClient();
client.Post(uri, content);
Run Code Online (Sandbox Code Playgroud)
但这会在 中创建另一个副本。XDocumentMemoryStream
XDocument.Save()期望 aStream可以写入。StreamContent期望一个可以读取的流。因此,您可以使用两个Streams,其中一个充当另一个的转发器。我认为框架中不存在这种类型,但你可以自己写一个:
class ForwardingStream\n{\n private readonly ReaderStream m_reader;\n private readonly WriterStream m_writer;\n\n public ForwardingStream()\n {\n // bounded, so that writing too much data blocks\n var buffers = new BlockingCollection<byte[]>(10);\n m_reader = new ReaderStream(buffers);\n m_writer = new WriterStream(buffers);\n }\n\n private class ReaderStream : Stream\n {\n private readonly BlockingCollection<byte[]> m_buffers;\n private byte[] m_currentBuffer;\n private int m_readFromCurrent;\n\n public ReaderStream(BlockingCollection<byte[]> buffers)\n {\n m_buffers = buffers;\n }\n\n public override void Flush()\n {}\n\n public override long Seek(long offset, SeekOrigin origin)\n {\n throw new NotSupportedException();\n }\n\n public override void SetLength(long value)\n {\n throw new NotSupportedException();\n }\n\n public override int Read(byte[] buffer, int offset, int count)\n {\n if (m_currentBuffer == null)\n {\n if (!m_buffers.TryTake(out m_currentBuffer, -1))\n {\n return 0;\n }\n m_readFromCurrent = 0;\n }\n\n int toRead = Math.Min(count, m_currentBuffer.Length - m_readFromCurrent);\n\n Array.Copy(m_currentBuffer, m_readFromCurrent, buffer, offset, toRead);\n\n m_readFromCurrent += toRead;\n\n if (m_readFromCurrent == m_currentBuffer.Length)\n m_currentBuffer = null;\n\n return toRead;\n }\n\n public override void Write(byte[] buffer, int offset, int count)\n {\n throw new NotSupportedException();\n }\n\n public override bool CanRead\n {\n get { return true; }\n }\n\n public override bool CanSeek\n {\n get { return false; }\n }\n\n public override bool CanWrite\n {\n get { return false; }\n }\n\n public override long Length\n {\n get { throw new NotSupportedException(); }\n }\n\n public override long Position\n {\n get { throw new NotSupportedException(); }\n set { throw new NotSupportedException(); }\n }\n }\n\n private class WriterStream : Stream\n {\n private readonly BlockingCollection<byte[]> m_buffers;\n\n public WriterStream(BlockingCollection<byte[]> buffers)\n {\n m_buffers = buffers;\n }\n\n public override void Flush()\n {}\n\n public override long Seek(long offset, SeekOrigin origin)\n {\n throw new NotSupportedException();\n }\n\n public override void SetLength(long value)\n {\n throw new NotSupportedException();\n }\n\n public override int Read(byte[] buffer, int offset, int count)\n {\n throw new NotSupportedException();\n }\n\n public override void Write(byte[] buffer, int offset, int count)\n {\n if (count == 0)\n return;\n\n var copied = new byte[count];\n Array.Copy(buffer, offset, copied, 0, count);\n\n m_buffers.Add(copied);\n }\n\n public override bool CanRead\n {\n get { return false; }\n }\n\n public override bool CanSeek\n {\n get { return false; }\n }\n\n public override bool CanWrite\n {\n get { return true; }\n }\n\n public override long Length\n {\n get { throw new NotSupportedException(); }\n }\n\n public override long Position\n {\n get { throw new NotSupportedException(); }\n set { throw new NotSupportedException(); }\n }\n\n protected override void Dispose(bool disposing)\n {\n m_buffers.CompleteAdding();\n\n base.Dispose(disposing);\n }\n }\n\n public Stream Reader\n {\n get { return m_reader; }\n }\n\n public Stream Writer\n {\n get { return m_writer; }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n不幸的是,您无法从同一线程同时读取和写入这些流。但您可以使用Task从另一个线程写入:
XDocument doc = \xe2\x80\xa6;\n\nvar forwardingStream = new ForwardingStream();\n\nvar client = new HttpClient();\nvar content = new StreamContent(forwardingStream.Reader);\n\nTask.Run(() => doc.Save(forwardingStream.Writer));\n\nvar response = client.Post(url, content);\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
3055 次 |
| 最近记录: |