Я пытаюсь прочитать поток HttpWebResponse, используя await / async:
async static Task testHttpWebClientAsync()
{
string url = "http://localhost/1.txt";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "GET";
HttpWebResponse resp = (HttpWebResponse)await req.GetResponseAsync();
Stream stream = resp.GetResponseStream();
stream.ReadTimeout = 10 * 1000;
byte[] buffer = new byte[1024];
while (await stream.ReadAsync(buffer, 0, buffer.Length) > 0)
{
//time out exception never thrown
}
}
Но это не работает, оно никогда не прерывается на ReadAsync.Для сравнения не асинхронная версия прекрасно работает с тем же тестовым сервером localhost:
static void testHttpWebClient()
{
string url = "http://localhost/1.txt";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "GET";
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
stream.ReadTimeout = 10 * 1000;
byte[] buffer = new byte[1024];
while (stream.Read(buffer, 0, buffer.Length) > 0)
{
//time out exception thrown here
}
}
Приведенный выше код протестирован в консольном приложении:
static void Main(string[] args)
{
testHttpWebClient();
MainAsync(args).GetAwaiter().GetResult();
}
async static Task MainAsync(string[] args)
{
await testHttpWebClientAsync();
}
Но это не относится кпроблема, действительно, я нахожу проблему в проекте WinForms и создаю консольный проект для проверки проблемы.
Для справки, код тестового сервера выглядит примерно так:
int c = 10;
byte[] ba = new byte[1024];
SendHeader(sHttpVersion, sMimeType,(int) ba.Length*c, " 200 OK", ref mySocket);
for (int k = 0; k < c; k++)
{
//set break point here
SendToBrowser(ba, ref mySocket);
}
Естьнесколько похожих тем на SO, но похоже, что ни одна из них не решает эту проблему.С точки зрения разработки API, очевидно, что нет причин, по которым ReadAsync () не срабатывает так же, как и Read (), ReadAsync должен наблюдать только за сокетом и событием внутреннего таймера, так работает Task.Delay ().Это не имеет ничего общего с CancellationToken и т. Д., Потому что нам не нужно ничего отменять, даже у ReadAsync есть версия, которая принимает CancellationToken.
Так что этот вопрос как для решения проблемы, так и почему ReadAsync нетайм-аут, как и ожидалось.