今天的主要工作是完成这个:
在命令行输入一个地方 输出该地方的实时天气和未来六天的天气信息
数据格式参考 http://www.cnblogs.com/danyueweb/p/3521973.html
涉及知识
JSON.NET/XML 读写/HttpClient , Async / Await
地区需要通过XML 保存到本地文件
当时的反应是,“看起来挺简单的样子。”
然后,“……等等JSON是什么玩意?”
那么是一步步来完成这个作业。
因为重点是为了熟悉异步编程,所以对界面的要求不高,只使用了控制台进行输出。于是我建了一个类来控制控制台打印输出。
因为给出的城市ID和名字只是文本,但是要求的是XML,所以顺手写了一个txt转xml的小程序生成了一个xml数据文件。
因为要在xml文件中进行查询,所以建了一个类进行xml文件的读写控制。
因为要把获取到的JSON字符串转换成正常的信息,所以建了一个JSON字符串处理类。
但是以上都还不是重点,重点是,我要用异步编程。
也不是没有写过多线程。之前在写Android的时候就有用过,和现在做的有点类似,都是为了防止从网络上获取信息的时候堵塞了UI主线程,造成卡死。那是非常明显的简单的多线程,我就继承一个Runnable,找一个句柄,然后我就跑起来了。
但是这个厉害的C# 5.0,把多线程封装了起来。虽然是封装得很好,但是除接触还是有点难理解。
这个程序的流程是很清晰明显的,我需要在主线程里另外开辟一个线程来进行信息获取,得到返回的信息后再打印出来。我建了一个HttpWeather类来进行数据获取的操作。
一开始,这个类里的函数只是返回值为String的普通函数,函数里面调用了HttpClient封装好的异步操作函数。
一跑起来就发现这不对。还没等到获得返回的信息,新的“请输入城市名”就已经打印出来了。
大概是因为要用await关键字?
也就是说,我要在主线程里等待至获得返回值,才能继续打印。
总而言之经过几个小时的调整,我终于写完了这个类。
class HttpWeather
{
static string addressBeg1 = "http://www.weather.com.cn/data/sk/";
static string addressBeg2 = "http://m.weather.com.cn/data/";
static string addressEnd = ".html";
public async Task<String> getWeatherCurrent(String cityID)
{
if (cityID == null)
return null;
string address = addressBeg1 + cityID + addressEnd;
HttpClient client = new HttpClient();
return await client.GetAsync(address).ContinueWith(
(requestTask) =>
{
HttpResponseMessage response = requestTask.Result;
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync().Result;
}
);
}
public async Task<String> getWeatherFuture(String cityID)
{
if (cityID == null)
return null;
string address = addressBeg2 + cityID + addressEnd;
HttpClient client = new HttpClient();
return await client.GetAsync(address).ContinueWith(
(requestTask) =>
{
HttpResponseMessage response = requestTask.Result;
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync().Result;
}
);
}
}
虽然只有短短几十行,但是在真是感觉打开了C#的新大门……大致上这几天的学习都快要推翻我之前对C#的认识了。
之后卢老师提醒的,可以将static字符串封装成类,也是我没有想过的想法。作为大学生的确在编程的很多方面不够规范有效,还需要更多的学习和学习和学习。