Monthly Archives: October 2013

Converting HTML to Xaml

My Windows 8 App whose code can be found here, uses a 3rd party API (Readability) to scrape the news sites such as Yahoo or CNN, so that the user sees only the text of the article and nothing more.  Ads and images are removed.

I am using the HTML Agility Pack to parse HTML and convert it to Xaml or a WinRT Visual Tree for display.  Right now, it’s all text.  The content of each paragraph, the <p> tag is  pulled out and placed into a TextBlock as a Run.  A style is applied to the TextBlock, so that the font is bigger than default, but nothing much else.

Now, I am working to add Images to the article view.  Images were easy to add, but captions are proving a more formidable obstacle.  Some sites use the alt attribute on the img tag to represent a caption.  Some also add a paragraph after the image to act as a caption.  Some do both. 

But some do neither.  So I cannot assume that the next paragraph after the image is the caption.  If anyone can figure out the solution to this problem, comment on this or email me feinbergaa at yahoo dot com
My

Windows RT 8.1 update

I upgraded my Surface to Windows 8.1 RT today.  the update went through without any issues, although the download took a while.  it’s a welcome refresher. I particularly like the fact that apps now have their own search bar embedded inside the app itself.  Searching no longer requires going to the charms bar. 

My year-old Surface also feels a bit more peppy after the update.  its a lot more pleasant to use it.  Standard Microsoft apps received a subtle facelift as well.  I especially like an updated Store app.  It’s a lot more fancy.  the on-screen keyboard is more user-friendly as well. 

There is a start button, but its functionality is of dubious value, it switches to Metro. 

 

Overall it’s a welcome upgrade, I like it, but it’s not revolutionary.  If you have Windows 8, I recommend upgrading.

SyndicationLink is not thread-safe or what’s the difference between await and Task.ContinueWith

My WinRT app was generating a ton of random crashes, which were difficult to debug. The crash dump harvested from customers by the Windows 8 system were all pointing to the same Accessviolation exception from unmanaged code.

There is only one place in my C# codebase which would result in the offending code being called,and it was protected by a try/catch block. So the first lesson I learned was that the regular try/catch does not save you from such memory exceptions.

Raising this issue on Microsoft Forums did not produce fruitful results. So… What is there to do?

Well, let’s start with the fact that these errors were almost impossible to reproduce. This points to threading issue.

Looking closer at this code:

var client = new SyndicationClient();
client.BypassCacheOnRetrieve = true;
      
var feed = client.RetrieveFeedAsync(_uri).ContinueWith( t =>
{ 
    var feed = t.Result;
    for each (var si in feed.Items)
     {
           if (si.Links.Count > 0)
            {
                //offending code below
                _link = si.Links[0].Uri; 
            }
     }
}
);

I began to suspect that something was releasing memory resources belonging to the feed and its items before the code retrieving the Uri from one of the syndication items runs.

How to fix this? Replace ContinueWith with the await call like this:

var client = new SyndicationClient();
client.BypassCacheOnRetrieve = true;
var feed = await client.RetrieveFeedAsync(_uri);
for each (var si in feed.Items)
{
    if (si.Links.Count > 0)
    {
       _link = si.Links[0].Uri; 
    }
}

So, what’s the difference? In the first example, the continuation runs on a thread that’s different from the one that initiated loading of the feed. By default, without specifying any additional parameters into the ContinueWith the delegate passed into it will be executed on a ThreadPool thread. So the thread that initiated the task, likely, creates the managed SyndicationFeed reference, and because the thread accessing it is different it’s likely causing this exception.

To use the ContinueWith method safely, you should pass the TaskScheduler.FromCurrentSynchronizationContext reference to the Task Scheduler. This would capture the current thread context and would use it to execute the delegate inside the continuation, making this approach equivalent to using the await.

References:
[1] Stack Overflow: http://stackoverflow.com/questions/8767218/is-async-await-keyword-equivalent-to-a-continuewith-lambda
[2] MSDN: http://msdn.microsoft.com/en-us/library/dd321307.aspx