Статьи

BackgroundCreation Сбой конструктора в Visual Studio? ОСТАНОВИТЬ ЭТО!

В Windows Phone Mango введено новое значение перечисления для создания растрового изображения, которое фактически загружает и декодирует изображение в фоновом потоке, а не в потоке пользовательского интерфейса. В некоторых случаях это дает ощутимые преимущества, но есть несколько проблемных моментов.

По умолчанию это все

По некоторым очень хорошим причинам это поведение по умолчанию отключено. Разработчики должны подписаться на это.

Это также означает, что 99% приложений там просто не используют его. В большинстве случаев это не имеет большого значения, но в некоторых случаях оно может заставить ваше приложение чувствовать себя намного быстрее.

Первоначально Автор Социальной Эболы

 

Так где же авария?

В Visual Studio, если вы попытаетесь использовать это свойство, при определенных обстоятельствах конструктор аварийно завершит работу (отобразит ошибку на поверхности конструктора):

System.Reflection.TargetInvocationException
Exception has been thrown by the target of an invocation.
   at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

System.InvalidOperationException
Layout measurement override of element 'Microsoft.Windows.Design.Platform.SilverlightViewProducer+SilverlightContentHost' should not return PositiveInfinity as its DesiredSize, even if Infinity is passed in as available size.
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Designer.DeviceSkinViewPresenter.DeviceDesignerBackground.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at Microsoft.Windows.Design.Interaction.DesignerView.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Designer.Viewport.MeasureOverride(Size availableSize)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Control.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Interop.HwndSource.SetLayoutSize()
   at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   at MS.Internal.DeferredHwndSource.ProcessQueue(Object sender, EventArgs e)

Так в чем проблема?

Проблема связана со средой выполнения, используемой в Visual Studio для отображения XAML WP7. В Visual Studio 2010 для этого используется механизм Silverlight, а в Silverlight, по-видимому, не реализовано это значение перечисления — и поэтому, если в XAML применяется DataContext во время разработки, Silverlight вылетает и вылетает, вызывая сообщение об ошибке, которое вы видите.

Как вы это решаете?

Может быть несколько способов ее решения, но мой включает в себя конвертер. Используйте элемент <Image> XAML, как обычно, но в разделе «Привязка источника» примените присоединенный конвертер с соответствующими параметрами:

<Image Source="{Binding Path=MyImage, Converter={StaticResource RuntimeImageLoaderConverter1}, ConverterParameter=bd}"/>

Очевидно, что конвертер должен быть объявлен в Ресурсах страницы или элемента управления. Интересным моментом является использование параметров конвертера:

ConverterParameter = шд

«B» обеспечит загрузку изображения в фоновом режиме (вышеупомянутый флаг BackgroundCreation), а «d» — загрузку с задержкой.

Вот и все — после того, как вы используете конструктор, система будет загружать изображение в обычном режиме (без фанк-флагов), когда в конструкторе, и с соответствующими флагами, когда фактически работает на телефоне.

Как это работает?

Это довольно просто, конвертер проверяет, находится ли он в среде разработки, и если это так, он будет создавать изображение по умолчанию. В противном случае он будет использовать соответствующие флаги (он также удостоверится, что знает, как загружать строковые URI и обычные URI):

public class RuntimeImageLoaderConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Uri uri = null;
        if (value is Uri)
        {
            uri = (Uri)value;
        }
        else if (value is String)
        {
            string s = (string)value;
            if (s.StartsWith("/"))
            {
                Uri.TryCreate(s, UriKind.Relative, out uri);
            }
            else
            {
                Uri.TryCreate(s, UriKind.Absolute, out uri);
            }
        }

        BitmapCreateOptions options = BitmapCreateOptions.None;

        string p = parameter as string;
        if (p != null && GetIsInDesignMode())
        {
            if (p.Contains("b") || p.Contains("B"))
            {
                options |= BitmapCreateOptions.BackgroundCreation;
            }

            if (p.Contains("d") || p.Contains("D"))
            {
                options |= BitmapCreateOptions.DelayCreation;
            }
        }

        BitmapImage result = null;
        if (uri != null)
        {
            result = new BitmapImage();
            result.CreateOptions = options;
            result.UriSource = uri;
        }

        return result;
    }

Вот и все. Надеюсь, это кому-нибудь поможет.:)

Скачать

Источник: http://socialebola.wordpress.com/2012/01/25/backgroundcreation-crashes-the-designer/