我试图在通用Windows项目中使用MVVM,但是用于存储文件的接口对使用异步有很多抱怨。以下代码有时有效:
public object Convert(object value, Type targetType, object parameter, string language)
{
var storageFile = value as StorageFile;
return GetImageAsync(storageFile).Result;
}
private static async Task<ImageSource> GetImageAsync(StorageFile storageFile)
{
var bitmapImage = new BitmapImage();
var stream = await storageFile.OpenAsync(FileAccessMode.Read).AsTask().ConfigureAwait(false);
bitmapImage.SetSource(stream);
return bitmapImage;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}在选择要加载的新映像之前,我将得到错误“{”,该应用程序称为一个接口,该接口是为另一个线程编组的。(HRESULT例外: 0x8001010E (RPC_E_WRONG_THREAD))"}“
因此,我尝试将其更改为在另一个线程中使用CoreDispatcher:
public class FileToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var storageFile = value as StorageFile;
Task<ImageSource> image = null;
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
image = GetImageAsync(storageFile);
image.RunSynchronously();
});
return image.Result;
}
private static async Task<ImageSource> GetImageAsync(StorageFile storageFile)
{
var bitmapImage = new BitmapImage();
var stream = await storageFile.OpenAsync(FileAccessMode.Read).AsTask().ConfigureAwait(false);
bitmapImage.SetSource(stream);
return bitmapImage;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}位图上的NullReferenceException。当然,这对我来说是绝对有意义的--异步调度程序将控件分配给父进程,没有分配映像,空引用异常。但我不知道什么是正确的方法!
发布于 2016-12-04 17:30:01
谢谢Clemens对OP的评论,这让我意识到我是模式迷,专注于使用我喜欢的东西,而不是做正确的设计。
引起这一问题的原因是:
private async void GetFile()
{
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add(".jpg");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".gif");
filePicker.FileTypeFilter.Add(".bmp");
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.Desktop;
filePicker.CommitButtonText = "Open";
CurrentFile = await filePicker.PickSingleFileAsync(); //Bad code used CurrentFile set and NotifyPropertyChanged to start up the value converter code from OP
//New, obvious better code
CurrentImage = await GetImageSource(CurrentFile);
var statistics = new ImageStatistics();
Logger.Log("Metadata start");
var data = statistics.GetMetaData(CurrentFile);
Logger.Log("Color Counts start");
var colorCounts = statistics.GetColorCounts(CurrentFile);
var filterer = new ColorFilterer();
Logger.Log("Color Counts await start");
var filteredColors = filterer.GetTopColors(await colorCounts, 10);
Logger.Log("Color Counts await end");
Logger.Log("Metadata await start");
var metaData = await data;
Logger.Log("Metadata await end");
Make = metaData[SystemProperty.CameraManufacturer];
Model = metaData[SystemProperty.CameraModel];
ExposureTime = string.Format("1/{0}",1/Convert.ToDouble(metaData[SystemProperty.ExposureTime]));
ISOSpeed = metaData[SystemProperty.ISOSpeed];
FStop = string.Format("f/{0}", metaData[SystemProperty.FStop]);
ExposureBias = metaData[SystemProperty.ExposureBias];
TopColors = filteredColors.Select(pair => new ColorStatistics { Color = pair.Key, Count = pair.Value }).ToList();
}所以,在图像被选中后,我只需要继续执行我想要的操作。这里还有很多要修复的地方,特别是因为我在执行工作时阻塞UI,而不是通过向属性订阅这些其他UI组件来委派这些操作,但是这是一个开始,没有更多的例外!
注意,这里不包括值转换器,它已经从主应用层中移除。
https://stackoverflow.com/questions/40952438
复制相似问题