我有一个WCF网络服务,它使用OpenAI的C#客户端调用一个生成模型。我希望将这个响应流式传输到WCF客户端。我当前的传输模式设置为“流式传输”,关闭超时时间为1秒。服务当前运行的代码的简化版本如下:
var collectionResult = openAiClient.CompleteChatStreaming(new[] { userMsg }, options: modelOptions);var stream = new MemoryStream();var sw = new StreamWriter(stream){ AutoFlush = true};Task.Run(async () =>{ foreach (var col in collectionResult) foreach (var data in col.ContentUpdate) sw.Write(data.Text);});stream.Position = 0;return stream;
在调试过程中,我发现外层循环甚至还没有开始,连接就被关闭了,我无法弄清楚原因。这是使用返回流的客户端代码片段:
using (var sr = new StreamReader(stream)){ var data = ""; while ((data = await sr.ReadLineAsync()) != null) { Console.WriteLine(data); }}
在WCF中,是否有办法实现这种服务器作为数据流入和流出的中间人的流式响应?如何正确实现?客户端需要能够看到模型输出,就像他们在与普通聊天机器人聊天一样,所以我不能等到整个响应生成完毕后再响应。
回答:
这段代码中有一个生产者和消费者在单个MemoryStream上操作。这行不通:
MemoryStream
只有一个Position
– 没有单独的读写位置- 在读写同时发生的情况下没有并发保护
- EOF是通过简单地到达末尾来隐式表示的,当什么都没写时,或者当读取器“赶上”时,立即为真
我认为你想要的是Pipe
,而不是MemoryStream
。Pipe
是一个不同的API,具有单独的生产者和消费者原语,支持背压(防止过度缓冲),以及明确的EOF,旨在用作此场景的缓冲区。