G. *_*nev 12 c# asynchronous c#-5.0 dotnet-httpclient
这是一个可以说明我的问题的剪辑:
using (var response = await _httpClient.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead))
{
var streamTask = response.Content.ReadAsStreamAsync();
//how do I check if headers portion has completed?
//Does HttpCompletionOption.ResponseHeadersRead guarantee that?
//pseudocode
while (!(all headers have been received))
//maybe await a Delay here to let Headers get fully populated
access_headers_without_causing_entire_response_to_be_received
//how do I access the response, without causing an await until contents downloaded?
//pseudocode
while (stremTask.Resul.?) //i.e. while something is still streaming
//? what goes here? a chunk-read into a buffer? or line-by-line since it's http?
...
Run Code Online (Sandbox Code Playgroud)
编辑为我澄清另一个灰色区域:
我发掘的任何引用都有某种阻塞语句,这将导致等待内容到达.引用我通常读取streamTask.Result或内容上的访问方法或属性,我不知道足以排除哪些引用是正常的,因为streamTask正在进行而哪些将导致等待直到任务完成.
根据我自己的测试,在你开始阅读内容流之前,内容不会被转移,而你是正确的,呼叫Task.Result是一个阻塞呼叫,但它的本质是,它是一个同步点.但是,它不会阻止预缓存整个内容,它只会阻止内容开始来自服务器.
所以无限的流不会阻塞无限的时间.因此,尝试异步获取流可能被视为过度,特别是如果您的头处理操作相对较短.但是,如果您愿意,您可以随时处理标题,同时在另一个任务上处理内容流.这样的事情会实现这一点.
static void Main(string[] args)
{
var url = "http://somesite.com/bigdownloadfile.zip";
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, url);
var getTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
Task contentDownloadTask = null;
var continuation = getTask.ContinueWith((t) =>
{
contentDownloadTask = Task.Run(() =>
{
var resultStream = t.Result.Content.ReadAsStreamAsync().Result;
resultStream.CopyTo(File.Create("output.dat"));
});
Console.WriteLine("Got {0} headers", t.Result.Headers.Count());
Console.WriteLine("Blocking after fetching headers, press any key to continue...");
Console.ReadKey(true);
});
continuation.Wait();
contentDownloadTask.Wait();
Console.WriteLine("Finished downloading {0} bytes", new FileInfo("output.dat").Length);
Console.WriteLine("Finished, press any key to exit");
Console.ReadKey(true);
}
Run Code Online (Sandbox Code Playgroud)
请注意,无需检查标题部分是否完整,您已使用该HttpCompletionOption.ResponseHeadersRead选项明确指定.该SendAsync任务将不会继续下去,直到头已经被取出.
使用await / async关键字的结果更具可读性:
var url = "http://somesite.com/bigdownloadfile.zip";
using (var httpClient = new HttpClient())
using (var httpRequest = new HttpRequestMessage(HttpMethod.Get, url ))
using(HttpResponseMessage response = await httpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead))
using (Stream stream = await response.Content.ReadAsStreamAsync())
{
//Access to the Stream object as it comes, buffer it or do whatever you need
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11161 次 |
| 最近记录: |