c# - Task.WaitAll not waiting on other async methods -


i'm asynchronously retrieving rss articles portable class library uses microsoft.bcl library (which doesn't have task.whenall). each article has url rss comments need asynchronously retrieve well.

the code below library. call getarticles() not return of creates list of tasks call getcomments() asynchronously comments.

i've tried using task.waitall in getarticles wait comments not block thread. appreciated.

    private const string articlesuri = "";      public async task<list<articlebrief>> getarticles()     {         var results = new list<articlebrief>();         try         {             var wfw = xnamespace.get("http://wellformedweb.org/commentapi/");             var media = xnamespace.get("http://search.yahoo.com/mrss/");             var dc = xnamespace.get("http://purl.org/dc/elements/1.1/");              var t = await webhttprequestasync(articlesuri);             stringreader stringreader = new stringreader(t);             using (var xmlreader = system.xml.xmlreader.create(stringreader))             {                 var doc = system.xml.linq.xdocument.load(xmlreader);                 results = (from e in doc.element("rss").element("channel").elements("item")                            select                                new articlebrief()                                {                                    title = e.element("title").value,                                    description = e.element("description").value,                                    published = convert.todatetime(e.element("pubdate").value),                                    url = e.element("link").value,                                    commenturi = e.element(wfw + "commentrss").value,                                    thumbnailuri = e.element(media + "thumbnail").firstattribute.value,                                    categories = getcategoryelements(e.elements("category")),                                    creator = e.element(dc + "creator").value                                }).tolist();              }              var tasks = new queue<task>();             foreach (var result in results)             {                 tasks.enqueue(                     task.factory.startnew(async ()=>                         {                             result.comments = await getcomments(result.commenturi);                         }                     ));             }              task.waitall(tasks.toarray());         }         catch (exception ex)         {             // should other             // logging here. pass off             // exception callback on ui             throw ex;         }          return results;     }      public async task<list<comment>> getcomments(string uri)     {         var results = new list<comment>();         try         {             var wfw = xnamespace.get("http://wellformedweb.org/commentapi/");             var media = xnamespace.get("http://search.yahoo.com/mrss/");             var dc = xnamespace.get("http://purl.org/dc/elements/1.1/");              var t = await webhttprequestasync(uri);             stringreader stringreader = new stringreader(t);             using (var xmlreader = system.xml.xmlreader.create(stringreader))             {                 var doc = system.xml.linq.xdocument.load(xmlreader);                 results = (from e in doc.element("rss").element("channel").elements("item")                            select                                new comment()                                {                                    description = e.element("description").value,                                    published = convert.todatetime(e.element("pubdate").value),                                    url = e.element("link").value,                                    creator = e.element(dc + "creator").value                                }).tolist();             }         }         catch (exception ex)         {             // should other             // logging here. pass off             // exception callback on ui             throw ex;         }          return results;     }      private static async task<string> webhttprequestasync(string url)     {         //todo: getting          var request = webrequest.create(url);         request.method = "get";          var response = await request.getresponseasync();         return readstreamfromresponse(response);     }      private static string readstreamfromresponse(webresponse response)     {         using (stream responsestream = response.getresponsestream())         using (streamreader sr = new streamreader(responsestream))         {             string strcontent = sr.readtoend();             return strcontent;         }     }      private list<string> getcategoryelements(ienumerable<xelement> categories)     {         var listofcategories = new list<string>();          foreach (var category in categories)         {             listofcategories.add(category.value);         }          return listofcategories;     } 

updated code solution, added .unwrap() on enqueue method:

            var tasks = new queue<task>();             foreach (var result in results)             {                 tasks.enqueue(                     task.factory.startnew(async ()=>                         {                             result.comments = await getcomments(result.commenturi);                         }                     ).unwrap());             }              task.waitall(tasks.toarray()); 

it waiting appropriately. problem creating task creates task (i.e. startnew returning task<task> , waiting on outer task completes rather (it completes before inner task complete)).

the questions be:

  • do want inner task?
    • if yes, can use task.unwrap proxy task represents completion of both inner , outer task , use wait on.
    • if no, remove use of async/await in startnew there not inner task (i think prefered, it's not clear why need inner task).
  • do need synchronous wait on asynchronous task? read of stephen cleary's blog: http://blog.stephencleary.com/2012/02/async-unit-tests-part-1-wrong-way.html

as aside, if not using c# 5, watch out closing on foreach variable result see


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -