尝试在 Windows Phone 上显示相机胶卷中的图像时出现跨线程异常

Posted

技术标签:

【中文标题】尝试在 Windows Phone 上显示相机胶卷中的图像时出现跨线程异常【英文标题】:Cross Thread Exception when trying to display Images from Camera Roll on Windows Phone 【发布时间】:2014-08-13 14:25:49 【问题描述】:

我正在使用可移植类库中的 Xamarin 构建 Windows 手机应用程序。我从 Windows Phone 相机胶卷中获取了图像,并将列表传递回 PCL 并将图像分配给我视图中的 ImageSource。

Windows Phone 获取图像:

foreach (var image in CameraRollPictures)

    Image img = new Image();
    img.Source = ImageSource.FromStream(() => image.GetImage());
    images.Add(img);
           
return images;

PCL 方法:

    private RelayCommand _importPhoto;
    public RelayCommand ImportPhoto
    
        get
        
            return _importPhoto
                ?? (_importPhoto = new RelayCommand(
                                      () =>
                                      
                                          IOperations op = DependencyService.Get<IOperations>();                                            
                                          Task<List<Image>> t = new Task<List<Image>>(() =>
                                          
                                              return op.ImportPhoto();

                                          );
                                          t.ContinueWith((sender) =>
                                              
                                                  PageOp.Navigate(new TaggingPage());
                                                  if (sender.Result.Count != 0)
                                                  
                                                      try
                                                      
                                                          App.Locator.TaggingPageVM.ImageSrc = sender.Result[0].Source;
                                                      
                                                      catch (Exception ex)
                                                      

                                                      
                                                  
                                              , TaskScheduler.FromCurrentSynchronizationContext());
                                          t.Start();
                                      ));

查看:

<Image Source="Binding ImageSrc"/>

例外情况:

System.UnauthorizedAccessException: 无效的跨线程访问。 在 MS.Internal.XcpImports.CheckThread() 在 System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex,IntPtr constructDO) 在 System.Windows.Media.Imaging.BitmapImage..ctor() 在 Xamarin.Forms.Platform.WinPhone.StreamImagesourceHandler.d__0.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在 Xamarin.Forms.Platform.WinPhone.ImageRenderer.d__0.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__3(对象 州)

更新

如果我从资源加载图片,那么它可以正常工作。

App.Locator.TaggingPageVM.ImageSrc = ImageSource.FromFile("50175950-tulips-microsofts.jpg");

在 windows phone 上创建的图像并将这些图像传回我的 PCL 一定是错误

【问题讨论】:

PageOp.Navigate 之后有代码,不确定这是个好主意。 PageOP.Navigate 基本上调用Navigation.PushAsync(Page) 然后App.Locator.TaggingPageVM 找到与此页面关联的VM 并设置ImageSrc 属性 您是否尝试过将该行包装在调用程序中? Deployment.Current.Dispatcher.BeginInvoke(() => App.Locator.TaggingPageVM.ImageSrc = sender.Result[0].Source; ); 我正在使用 Xamarin 但我使用了 Device.BeginInvokeOnMainThread(() => App.Locator.TaggingPageVM.ImageSrc = sender.Result[0].Source; );这是一种类似的方法并且有效 【参考方案1】:

我正在使用 Xamarin:

Device.BeginInvokeOnMainThread(() =>  App.Locator.TaggingPageVM.ImageSrc = sender.Result[0].Source; ); 

修复了跨线程错误

【讨论】:

我不完全确定导致此异常的原因,但我认为它与 UI 线程有关。我使用 Xamarin 连接插件得到了这个异常。每当连接状态发生变化时,我都会尝试更新一个标签,说明如果应用程序在代码到达该指令时正在做一些后台工作,我会得到异常。我用“Device.BeginInvokeOnMainThread ...”包围了更新标签指令,从那时起就没有出现异常

以上是关于尝试在 Windows Phone 上显示相机胶卷中的图像时出现跨线程异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中显示相机胶卷图像文件名列表

修剪后无法在相机胶卷中显示视频

Xamarin 表单文件选择器未在 ios 上显示相机胶卷或图像库

无法将视频保存到相机胶卷(目标 C)

为啥我的相机胶卷模式是空的?

在 viewDidLoad 外部调用方法时未显示相机胶卷中的最后一张图像