问题
I have an news aggregator and in debug i have the following: Skipped 675 frames! The application may be doing too much work on its main thread. I am loading only from 12 sites. Is there a way to to do all this loading in background without the whole app freezing?
EDIT: Method to get one news
public async static Task<NewsContent> oneNews(string category,string site)
{
if(sites.Count==0)
addElements();
GetNews gn = new GetNews(site,false);
Random rn = new Random();
var s = await gn.news(rn.Next(0,2));
return s;
}
The GetNews class:
class GetNews
{
string url;
bool isMultiple;
public GetNews(string url,bool isMultiple)
{
this.url = url;
this.isMultiple = isMultiple;
}
public async Task<NewsContent> news(int i)
{
List<NewsContent> feedItemsList = new List<NewsContent>();
try
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(stream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
nsmgr.AddNamespace("dc", xmlDocument.DocumentElement.GetNamespaceOfPrefix("dc"));
nsmgr.AddNamespace("content", xmlDocument.DocumentElement.GetNamespaceOfPrefix("content"));
XmlNodeList itemNodes = xmlDocument.SelectNodes("rss/channel/item");
NewsContent feedItem = new NewsContent();
if (itemNodes[i].SelectSingleNode("title") != null)
{
feedItem.title = itemNodes[i].SelectSingleNode("title").InnerText;
}
if (itemNodes[i].SelectSingleNode("link") != null)
{
feedItem.url = itemNodes[i].SelectSingleNode("link").InnerText;
}
if (itemNodes[i].SelectSingleNode("pubDate") != null)
{
var time = itemNodes[i].SelectSingleNode("pubDate").InnerText;
feedItem.time = getHour(time);
}
if (itemNodes[i].SelectSingleNode("description") != null)
{
feedItem.desc = itemNodes[i].SelectSingleNode("description").InnerText;
}
if (itemNodes[i].SelectSingleNode("content:encoded", nsmgr) != null)
{
feedItem.content = itemNodes[i].SelectSingleNode("content:encoded", nsmgr).InnerText;
}
else
{
feedItem.content = feedItem.desc;
}
feedItem.imageURL = getImage(feedItem.content);
var sourcename = url.Split(new[] { "//" }, StringSplitOptions.None)[1];
feedItem.newsSource = sourcename.Split(new[] { "/" }, StringSplitOptions.None)[0];
if (feedItem.content.Contains("<p>"))
{
var shortContent = feedItem.content.Split(new[] { "<p>" }, StringSplitOptions.None)[1];
string finalShortContent = "";
for (int ii = 0; ii < shortContent.Length; ii++)
{
if (ii > 200 && shortContent[ii].Equals(' '))
break;
while (shortContent[ii].Equals('<') || shortContent[ii].Equals('p') || shortContent[ii].Equals('/') || shortContent[ii].Equals('>'))
ii++;
try
{
finalShortContent += shortContent[ii];
}
catch (Exception e)
{
break;
}
}
finalShortContent += "...";
feedItem.shortcontent = finalShortContent;
}
return feedItem;
}
catch (Exception e)
{
return null;
}
}
string getImage(string full)
{
try
{
var code = full.Split(new[] { "src=\"" }, StringSplitOptions.None)[1];
var fin = code.Split(new[] { "\"" }, StringSplitOptions.None)[0];
return fin;
}
catch(Exception e)
{
return null;
}
}
List<int> getHour(string full)
{
try
{
List<int> smh = new List<int>();
var ph = full.Split(new[] { "2020 " }, StringSplitOptions.None)[1];
var hour = ph.Split(new[] { ":" }, StringSplitOptions.None);
smh.Add(Int32.Parse(hour[0]));
smh.Add(Int32.Parse(hour[1]));
var second = hour[2].Split(new[] { " " }, StringSplitOptions.None)[0];
smh.Add(Int32.Parse(second));
return smh;
}catch(Exception)
{
return null;
}
}
}
回答1:
Try this. It should put the function in another thread
await Task.Run(async () =>
{
//function
});
来源:https://stackoverflow.com/questions/61370839/skipped-675-frames-the-application-may-be-doing-too-much-work-on-its-main-threa