سؤال

أقوم بتحميل صور المستخدم باستخدام Silverlight 3. كل شيء يعمل بشكل جيد ويمكنني تعيين دفق الملف على BitmapImage ويصبح موافق.

المشكلة هي أنه إذا حاولت تحميل شيء ليس صورة (مثل .exe تم إعادة تسميتها إلى .png) تعطل Silverlight مع أ 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.

قد يكون هناك خيار أفضل ، ولكن إحدى الطرق التي وجدتها في العمل حول هذه الاستثناءات التي لا يمكن التعامل معها بطريقة أخرى هي تعديل طريقة App.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); });
    }
}

إنه اختراق ولا أحب ذلك ، لكنه أفضل من استثناء غير معقول.

راجع للشغل ، يجب عليك حقًا تقديم خطأ في هذا السلوك. من المؤكد أنها تفشل في "قانون أدنى دهشة". انظر منشور تيم هوير حول كيفية رفع الأخطاء: http://timheuer.com/blog/archive/2010/05/03/ways-to-give-feedback-on-silverlight.aspx

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top