Визуализация значка программы в Image Control с использованием TPL - PullRequest
0 голосов
/ 07 октября 2011

Привет, я пытаюсь создать интерактивность. Поведение для загрузки значка программы в фоновом режиме. Ниже приведен код, но он дал мне. Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку ..

protected override void OnAttached()
    {
        base.OnAttached();

        if (!string.IsNullOrEmpty(Url))
        {
            Icon ico = Icon.ExtractAssociatedIcon(Url);
            if (ico != null)
            {

               taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                Task.Factory.StartNew(() => {
                                                MemoryStream ms = new MemoryStream();
                                                ico.ToBitmap().Save(ms, ImageFormat.Png);
                                                ms.Position = 0;
                                                BitmapImage bi = new BitmapImage();
                                                bi.BeginInit();
                                                bi.StreamSource = ms;
                                                bi.EndInit();
                                                return bi;
                                            }).ContinueWith((t) => AssociatedObject.Source = t.Result, taskScheduler);




            }

        }
    }

Ответы [ 2 ]

0 голосов
/ 07 октября 2011

WPF-объекты (все, что происходит от DispatcherObject ) являются аффинно-потоковыми - обычно их можно использовать только в потоке, который их создал.Это включает в себя BitmapImage объектов.Если вы создаете BitmapImage в фоновом потоке, его можно использовать только из этого фонового потока - это означает, что поток UI получит ошибку при попытке отобразить растровое изображение.

Однако BitmapImage снижаетсяот Freezable .Freezable имеет метод Freeze , который сделает экземпляр доступным только для чтения.И в соответствии с « Обзор замораживаемых объектов » на MSDN:

Замороженный Freezable также может быть разделен между потоками, в то время как незамерзающий Freezable не может.

Таким образом, если вы добавите вызов к bi.Freeze(); непосредственно перед возвратом изображения из фоновой задачи, вы сможете успешно использовать изображение из потока пользовательского интерфейса.

0 голосов
/ 07 октября 2011

Несмотря на то, что вы используете CurrentSynchronizationContext, попробуйте, если может потребоваться запустить на Dispatcher значка ....

    ico.Dispatcher.BeginInvoke(
         new Action(
           () =>
           {
              ico.ToBitmap().Save(ms, ImageFormat.Png); 
              ///rest of the code that uses `ms`.
           }));

Предложение : Почему нетВы используете Priority Binding и Binding.IsAsync для медленной загрузки изображений ....

http://social.msdn.microsoft.com/Forums/en-AU/wpf/thread/b3dc9baa-4cf6-49ed-a316-b9fb1cd29516

...