在 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;
}
}
我正在做一个 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;
}
}