3

这是我的情况,我有两个 Web api 服务。第一个有一个处理一些数据的方法,当部分数据准备好时,它会将其推送到流中。

public HttpResponseMessage Get( )
        {
            var response = Request.CreateResponse( );
            response.Content = new PushStreamContent( WriteToStream );
            return response;
        }

        public async void WriteToStream( Stream outputStream, HttpContent content, TransportContext context )
        {
            .......
        }

第二个 web api 在控制器中有一个调用第一个 web api 的方法。它必须从流中读取部分对其进行处理并将 i 放入它自己的流中:

public HttpResponseMessage Get( )
        {
            Stream stream = null;

            using( HttpClient httpClient = new HttpClient( ) )
            {
                httpClient.Timeout = TimeSpan.FromMilliseconds( Timeout.Infinite );
                HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Get, "http://localhost/fistWebApi/" );

                var response = httpClient.SendAsync( request, HttpCompletionOption.ResponseContentRead );

                var content = response.Result.Content.ReadAsStreamAsync( );

                stream = content.Result;
            }

            var msg = Request.CreateResponse( );

            msg.Content = new PushStreamContent( WriteToStream );

            return msg;
        }
public async void WriteToStream( Stream outputStream, HttpContent content, TransportContext context )
            {
                .......
            }

问题是我不知道如何同步调用SendAsync ReadAsStreamAsync。现在它不会等待并且stream在尝试使用它时没有正确初始化。我希望第二种方法的代码等到第一种方法将部分数据放入流中。我尝试使用ContinueWith,但后来我无法做到。如果有任何问题我会尝试更深入地解释,我知道这是一个有点模糊的解释。

4

1 回答 1

10

尝试这个...

 public HttpResponseMessage Get()
        {

            using (HttpClient httpClient = new HttpClient())
            {
                httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://www.google.ca");

                return httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
                    .ContinueWith((t) =>
                        {
                            return new HttpResponseMessage()
                                {
                                    Content = t.Result.Content
                                };
                        }).Result;

            }

        }

上面的代码对我有用。这样做的缺点是,因为您使用HttpCompletionOption.ResponseContentRead了来自远程服务的整个有效负载,所以在返回客户端之前将对其进行缓冲。

如果改为使用HttpCompletionOption.ResponseHeadersReadt.Result.Content 返回网络流。这样,当您的客户端拉取响应流时,它将直接从远程资源流式传输。我假设这就是您当前正在尝试对您返回的 PushStreamContent 执行的操作。

于 2013-04-06T18:38:54.673 回答