在 UI 个线程上执行 MVVMCross 值转换器逻辑

Execute MVVMCross value converter logic on UI thread

我正在做一个 Xamarin.iOS 项目,并且有一个 MVVMCross 值转换器,它采用文件扩展名字符串和 returns 相应的文件图标作为 UIImage

此转换器用于文件列表。我发现当我滚动列表时,一旦 MvxTableViewCell 被回收,UI 转换器经常在后台线程中为回收的单元调用,使我的代码抛出错误抱怨从后台线程调用 UIKit 方法。

看起来在最新版本的MVVMCross中,旧的IMvxMainThreadDispatcher.RequestMainThreadAction方法已经过时了。文档建议使用 IMvxMainThreadAsyncDispatcher.ExecuteOnMainThreadAsync 方法。

但是,此方法 returns 没有泛型类型 Task。这显然不能与期望 UIImage.

的值转换器的 Convert 方法一起使用

有没有办法将 MVVMCross 配置为始终在 UI 线程上调用转换器?

更新:

以下面的代码为例:

public class FileIconConverter : MvxValueConverter<string, UIImage>
{
    protected override UIImage Convert(string fileExtension, Type targetType, object parameter, CultureInfo culture)
    {
        // When this is called, it could be in a background thread.
        // Since UIDocumentInteractionController.FromUrl requires to be called
        // on the UI thread, it would throw the UIKitThreadAccessException.
        return UIDocumentInteractionController.FromUrl(NSUrl.FromFilename("/tmp/generic" + fileExtension)).Icons[0];
    }
}

既然你没有在这里添加任何代码,我能做的就是给你一些推测性的建议。

你可以做的是使用Xamarin.iOS

InvokeOnMainThread方法

当您在 Working with the UI Thread in Xamarin.iOS

上查看 Xamarin.iOS 文档时

您可以看到您使用此方法进行了应该在 UI

上进行的更改
InvokeOnMainThread ( () => {
// manipulate UI controls
});

更新

首先,如果您在 MvvmCross's Git 检查 IMvxMainThreadDispatcher.RequestMainThreadAction 的代码,它在内部调用相同的 API!

所以您可以对现有代码执行的操作类似于

public class FileIconConverter : MvxValueConverter<string, UIImage>
{
protected override UIImage Convert(string fileExtension, Type targetType, object parameter, CultureInfo culture)
  {
    UIImage image;
    IMvxMainThreadAsyncDispatcher.ExecuteOnMainThreadAsync(()=>{

    image=UIDocumentInteractionController.FromUrl
               (NSUrl.FromFilename("/tmp/generic" + fileExtension)).Icons[0];


  });
    return image;
 }
}