异常函数的写法:
public static Task<string> HttpGetAsync(string url, Dictionary<string, string> headers = null)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
if (headers != null)
{
foreach (var header in headers)
request.Headers[header.Key] = header.Value;
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
return streamReader.ReadToEndAsync();
}
}
catch (Exception ex)
{
return Task.FromResult(ex.Message);
}
}
在异步调用以上函数,使用return streamReader.ReadToEndAsync()的结果时,可能会抛出以下异常提示:
Unable to read data from the transport connection: Operation canceled.
Specified argument was out of the range of valid values.
即异步IO 中的网络流是异步输入的,在await使用该方法的返回结果时,可能会遇到流还没读取完的情况,如果此时将结果字符串进行json反序列化的使用,可能会报遇到意外终止符等异常。
优化写法:
public static async Task<string> HttpGetAsync(string url, Dictionary<string, string> headers = null)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
if (headers != null)
{
foreach (var header in headers)
request.Headers[header.Key] = header.Value;
}
var result=string.Empty;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using(Stream responseStream = response.GetResponseStream())
{
using(StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8))
{
result = await streamReader.ReadToEndAsync();
streamReader.Close();
}
responseStream.Close();
}
response.Close();
}
return result;
}
catch (Exception ex)
{
return ex.Message;
}
}
使用await在函数内同步获取完全结果后,依次释放对象的使用和对流进行关闭。