Art*_*t W 9 c# asynchronous webclient c#-5.0 async-ctp
我有这两种方法,我想运行异步以保持UI响应.但是,它仍然悬挂着UI.有什么建议?
async void DoScrape()
{
var feed = new Feed();
var results = await feed.GetList();
foreach (var itemObject in results)
{
var item = new ListViewItem(itemObject.Title);
item.SubItems.Add(itemObject.Link);
item.SubItems.Add(itemObject.Description);
LstResults.Items.Add(item);
}
}
public class Feed
{
async public Task<List<ItemObject>> GetList()
{
var client = new WebClient();
string content = await client.DownloadStringTaskAsync(new Uri("anyUrl"));
var lstItemObjects = new List<ItemObject>();
var feed = new XmlDocument();
feed.LoadXml(content);
var nodes = feed.GetElementsByTagName("item");
foreach (XmlNode node in nodes)
{
var tmpItemObject = new ItemObject();
var title = node["title"];
if (title != null) tmpItemObject.Title = title.InnerText;
var link = node["link"];
if (link != null) tmpItemObject.Link = link.InnerText;
var description = node["description"];
if (description != null) tmpItemObject.Description = description.InnerText;
lstItemObjects.Add(tmpItemObject);
}
return lstItemObjects;
}
}
Run Code Online (Sandbox Code Playgroud)
spe*_*der 12
我怀疑DownloadStringTaskAsync是HttpWebRequest.BeginGetResponse在较低的水平上依赖.在这种情况下,已知webrequest的设置不是完全异步的.恼人地(坦率地说,愚蠢地)异步WebRequest的DNS查找阶段是同步执行的,因此会阻塞.我怀疑这可能是你正在观察的问题.
以下转载的是文档中的警告:
你有两个选择:
我们选择了实现我们自己的正确异步HTTP库以获得不错的吞吐量的第三个(也是昂贵的)选项,但在您的情况下它可能有点极端;)
你似乎混淆了并行异步.它们都基于任务,但它们完全不同.不要假设async方法并行运行 - 它们不会.
Async默认在同一个线程中工作,除非有理由强制异步引擎启动新线程,例如主线程没有消息泵的情况.但总的来说,我倾向于认为async关键字在同一个线程中运行.
您使用WinForms,因此UI线程有一个消息泵.因此,上面的所有代码都在UI线程中运行.
你必须明白,你没有在这里引入任何并行性.您通过async关键字引入的是异步操作,而不是并行操作.您没有做任何"让您的UI响应",除了那个DownloadStringTaskAsync不会强迫您等待数据到达的调用,但您仍然必须在所有网络处理(DNS查找等) UI线程 - 这是正在进行的异步操作(基本上"节省"等待下载的时间).
为了保持UI的响应性,您需要将耗时的工作分拆到单独的线程中,同时保持UI线程的自由.你不是用async关键字做的.
您需要使用Task.Factory.StartNew(...)显式启动新线程来进行后台处理.
| 归档时间: |
|
| 查看次数: |
4021 次 |
| 最近记录: |