最接近的是
public async Task<IEnumerable<dynamic>> GetResults(string id, int n) {
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Token " + token);
Stream results = await client.GetStreamAsync(baseurl + id + "/results");
StreamReader sr = new StreamReader(results);
while(!sr.EndOfStream) {
string line = await sr.ReadLineAsync();
yield return Json.Decode(line);
}
}
但是它说它不能是迭代器块,因为System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<dynamic>>
不是迭代器接口类型。
然而,我找不到一种方法来获得没有异步方法的流(我只能找到GetStreamAsync,没有GetStream的定义),这迫使我有一个异步方法,这迫使我返回一个Task。
设法使用WebRequest类并遵循该页面的示例:
public IEnumerable<dynamic> GetResults(string id, int n) {
WebRequest request = WebRequest.Create(baseurl + id + "/results");
request.Headers.Add("Authorization", "Token " + token);
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
while(!sr.EndOfStream) {
string line = sr.ReadLine();
yield return Json.Decode(line);
}
}
WebResponse有GetResponseStream
,而HttpClient
只有GetStreamAsync
。这允许我不必等待,也没有async方法
为了流式处理响应,您必须手动写入响应流。您可以使用PushStreamContent
,并传入一个委托,该委托在准备发送时立即将一行写入输出流:
public HttpResponseMessage GetResults(string id, int n) {
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Token " + token);
Stream results = await client.GetStreamAsync(baseurl + id + "/results");
response.Content = new PushStreamContent(
async (outputStream, httpContent, transportContext) => {
using(outputStream)
{
StreamReader sr = new StreamReader(results);
while(!sr.EndOfStream)
{
string line = await sr.ReadLineAsync();
var decoded = Json.Decode(line);
//convert to byte array
byte[] buffer = //...
await outputStream.WriteAsync(buffer, 0, buffer.Length);
}
}
});
}
参见ASP中的异步流。. NET WebApi .
老回答
正如编译器所说,您需要返回IEnumerable
或IEnumerator
。
如果你返回一个Task<IEnumerable<T>>
,客户端如何处理它?foreach
在可枚举对象上调用MoveNext()
——相反,它必须调用await MoveNext
。IEnumerable
和Task<IEnumerable>
不能互换
你必须在返回一个可枚举对象给客户端之前收集你的结果。
public async Task<IEnumerable<dynamic>> GetResults(string id, int n) {
//...
StreamReader sr = new StreamReader(results);
List<string> results = new List<string>();
while(!sr.EndOfStream) {
string line = await sr.ReadLineAsync();
results.Add(line);
}
return results;
}