优雅地处理图像负载异常
-
04-10-2019 - |
题
我正在使用Silverlight 3加载用户图像。一切正常,我可以将文件流设置为 BitmapImage
而且它变得还不错。
问题是,如果我尝试加载不是图像的东西(例如,已重命名为.png的.exe)Silverlight用A崩溃 System.Exception
那就是“灾难性的失败”。 MSDN文档无用地说应该这样做 MSDN链接 我应该听 ImageFailed
事件(永远不会被解雇)。
我在那里缺少某些东西,还是从流中加载时库会损坏?
我已经从源加载图像的代码:
var openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "*.jpg;*.jpeg;*.png|*.jpg;*.jpeg;*.png";
openFileDialog.Multiselect = false;
var showDialog = openFileDialog.ShowDialog();
if (showDialog.HasValue && showDialog.Value)
{
using (var reader = openFileDialog.File.OpenRead())
{
var picture = new BitmapImage();
picture.DownloadProgress += (o, e) => System.Threading.SynchronizationContext.Current.Send((oo) => System.Windows.Browser.HtmlPage.Window.Alert("Download progress: " + e.Progress), null);
picture.ImageFailed += (o, e) => System.Threading.SynchronizationContext.Current.Send((oo) => System.Windows.Browser.HtmlPage.Window.Alert("Image failed: " + e.ErrorException), null);
picture.ImageOpened += (o, e) => System.Threading.SynchronizationContext.Current.Send((oo) => System.Windows.Browser.HtmlPage.Window.Alert("Image opened: " + e.OriginalSource), null);
picture.SetSource(reader); // BANG! here without any of the alerts showing up
}
}
解决方案
这很奇怪,但是您是对的,即使在Silverlight 4上,它也是如此。
可能有一个更好的选择,但是我发现解决这些异常的一种方法是修改application_unhandledexception()方法。这对您有用:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
// Handle stupid image load exception. Can't think of a better way to do it -- sorry.
if (e.ExceptionObject is System.Exception && e.ExceptionObject.Message.Contains("HRESULT") && e.ExceptionObject.Message.Contains("E_UNEXPECTED"))
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Error loading image.");
});
e.Handled = true;
return;
}
// If the app is running outside of the debugger then report the exception using
// the browser's exception mechanism. On IE this will display it a yellow alert
// icon in the status bar and Firefox will display a script error.
if (!System.Diagnostics.Debugger.IsAttached)
{
// NOTE: This will allow the application to continue running after an exception has been thrown
// but not handled.
// For production applications this error handling should be replaced with something that will
// report the error to the website and stop the application.
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
这是一个黑客,我不喜欢它,但是比未经治疗的例外要好。
顺便说一句,您真的应该就此行为提交一个连接错误。当然,这使“最少惊讶的法律”失败了。请参阅Tim Heuer关于如何提交错误的帖子: http://timheuer.com/blog/archive/2010/05/03/ways-to-give-five-feedback-on-silverlight.aspx
不隶属于 StackOverflow