简体   繁体   中英

Why does setting the XAML property on a RichTextBox to this value crash Silverlight?

While doing some testing of a HTML to XAML converter I'm working on, I ran across a strange situation that I can't explain. Due to a bug in my HTML to XAML converter I was given this XAML:

<Section xml:space="preserve" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />

When I set the XAML property of the RichTextBox to this string it ignores my try/catch and crashes the entire app with this error:

System.AccessViolationException was unhandled Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

My code is simple:

try {
    rtb.Xaml = ptb.Text;
} catch (Exception ex) {
    MessageBox.Show(ex.Message);
}

Why is this exception not caught? I tried adding an AccessViolationException catch, but that didn't change anything. Thank you for your time.

(Note: this is Silverlight 4)

Not sure its useful but this is what I found out:

The Xaml property inside the RichTextBox uses XamlReader to parse the Xaml. This is native code under the hoods. The exception is thrown inside native code, which aint always the most useful exceptions.

For some reason the XamlReader doesn't accept a selfclosing Section tag.

// Gives AccessViolationException.
XamlReader.Load("<Section xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" />");

// Valid...
XamlReader.Load("<Section xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"></Section>");

To make things more weird, for some reason the TextBlock does accept a selfclosing tag.

// Valid...
XamlReader.Load("<TextBlock xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" />");

// Valid...
XamlReader.Load("<TextBlock xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"></TextBlock>");

I am not sure but maybe its because inside the XamlReader the Section part expects a child node or something like that as for TextBlock it doesn't.

Silverlight obviously requires that we do most things in an "asynchronous" fashion, and that adds a variety of weirdnesses for error trapping. My suspicion is that something like this is happening here. Presumably the call to XamlReader.Load() is kicking off a operation that is executing asynchronously (though perhaps on the same thread, through something like Dispatcher.BeginInvoke()), and when that operation encounters an error, it doesn't get caught by the normal try/catch mechanism, because execution has moved on beyond the catch() clause.

For instance, this code will throw an unhandled error:

try
{
    Deployment.Current.Dispatcher.BeginInvoke(() => throw new Exception("Sucks to be you."));
}
catch(System.Exception ex)
{
     ErrorMessageBox.Show(ex.Message);
}

I'd bet good money that there's a Dispatcher.BeginInvoke() hiding somewhere in the depths of the XAML parser.

For what it's worth, something similar happens with BitmapImage.SetSource(). See this question here: Handling image load exception gracefully

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM