如何在C#中通过http远程处理执行分块时返回字节[]?

如何在C#中通过http远程处理执行分块时返回字节[]?,c#,remoting,bytearray,byte,chunking,C#,Remoting,Bytearray,Byte,Chunking,在http上的.Net远程处理中,我们通过执行SerializationInfo.AddValue(SerializationInfoValueName,((MemoryStream)writer.BaseStream).GetBuffer(),typeof(byte[])调用将字节[]返回给客户端 但是,有时字节[]的大小太大,导致OutOfMemory异常。唯一的补救办法似乎是利用某种形式的分块。转向WCF似乎是最合乎逻辑的,但这在不久的将来是不可能的 那么,关于如何实现通用分块解决方案,有

在http上的.Net远程处理中,我们通过执行SerializationInfo.AddValue(SerializationInfoValueName,((MemoryStream)writer.BaseStream).GetBuffer(),typeof(byte[])调用将字节[]返回给客户端

但是,有时字节[]的大小太大,导致OutOfMemory异常。唯一的补救办法似乎是利用某种形式的分块。转向WCF似乎是最合乎逻辑的,但这在不久的将来是不可能的


那么,关于如何实现通用分块解决方案,有什么建议吗

没有内置的分块。您需要自己实现它。这应该很简单

一些类似以下的界面应该可以做到这一点:

Guid GetFile(string filename);
Guid GetFile(string filename, out int chunkCount);
byte[] GetFileChunk(Guid id, int chunkIndex);
调用
GetFile()
时,服务器可以根据充当键的
Guid
将文件“缓存”到
字典中。然后可以将这个
Guid
返回给客户端,以便它可以进一步请求下载文件的实际块

GetFileChunk()
如果chunkIndex超过该Guid/文件的块数,则应返回null

块的大小取决于您。您可以在响应能力和性能之间进行选择。块越大,性能越好。但是,如果您正在更新GUI上的进度条或其他内容,那么“响应性”当然会受到不利影响。试着用最有效的方法进行实验

替代接口可能类似于:

Guid GetFile(string filename, out ulong numOfBytes);
byte[] GetFileData(Guid id, ulong index, ulong count);

这意味着客户端可以决定希望下载的块的大小。然后您可以实施某种扩展策略。

解决方案实际上取决于服务器上的资源是否易于“查找”。例如,如果您要创建一个简单的远程处理服务,它只访问一个文件并返回其内容,那么这将是一个非常简单的服务。您只需要让客户端传入所需的偏移量和要检索的数据长度

但是,如果在服务器上生成的数据更复杂,并且需要在一个逻辑调用中完成调用,则可能需要深入研究

我已经很久没有使用.NET远程处理了,但是由于流是从MarshalByRefObject派生的,所以您可以通过引用客户端来返回流。但是,这可能会变得很棘手,因为您现在使用的服务器端对象的生命周期比逻辑操作的生命周期长,这可能会带来可伸缩性问题,并且如果您决定稍后升级,在WCF中没有直接的类比


值得一提的是,数据是通过其内置协议传输的。

更安全的方法是在从服务器返回的对象上远程传输流。Stream扩展了MarshalByRefObject,因此,如果在发送到客户端的对象中包含对开放流的引用(例如,指向要发送的文件数据或缓冲区),则在调用流代理上的方法时,客户端将回调服务器。这样,客户端可以使用它想要的任何缓冲区大小(在合理范围内)来移动数据。

我不确定这是否可行?你以前试过吗?是的,效果很好。几年前(在我切换到WCF之前),我基于这个概念构建了一个大型系统。这是个好主意,但这种解决方案可能最终需要更多的开销,并影响可伸缩性。你怎么认为?