我有一个代码,它应该从文件夹中获取所有图片,将它们放入名为" PhotoInspection"的对象中,添加一些信息并将此对象放入列表中。请参阅以下代码
private async void btnSend_Click(object sender, RoutedEventArgs e)
{
bool isOn = tsOnOff.IsOn;
TextBlock tbChosen = new TextBlock();
tbChosen = lbInspections.SelectedItem as TextBlock;
string chosen = tbChosen.Text;
AllInspectionPhotos aip = new AllInspectionPhotos();
var folders = await ApplicationData.Current.LocalFolder.GetFoldersAsync();
if (isOn)
{
foreach (var item in folders)
{
if (item.Name == "ONLINE")
{
var inspectionFolders = await item.GetFoldersAsync();
foreach (var inspectionFolder in inspectionFolders)
{
if (inspectionFolder.Name == chosen)
{
aip.InspectionEan = chosen;
var photos = await inspectionFolder.GetFilesAsync();
foreach (var photo in photos)
{
using (Stream stream = await photo.OpenStreamForReadAsync())
{
PhotoInspection phtInsp = new PhotoInspection();
var bytes = new byte[(int)stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
phtInsp.Photo = bytes;
phtInsp.InspectionEan = chosen;
phtInsp.PhotoName = photo.Name;
aip.Photos.Add(phtInsp);
}
}
}
}
}
}
}
else
{
foreach (var item in folders)
{
if (item.Name == "OFFLINE")
{
var inspectionFolders = await item.GetFoldersAsync();
foreach (var inspectionFolder in inspectionFolders)
{
if (inspectionFolder.Name == chosen)
{
aip.InspectionEan = chosen;
var photoset = await inspectionFolder.GetFilesAsync();
foreach (var photo in photoset)
{
PhotoInspection phtInsp = new PhotoInspection();
using (Stream stream = await photo.OpenStreamForReadAsync())
{
var bytes = new byte[(int)stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
phtInsp.Photo = bytes;
phtInsp.InspectionEan = chosen;
phtInsp.PhotoName = photo.Name;
}
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
//await App._client.SendPhotoAsync(phtInsp);
aip.Photos.Add(phtInsp); //fires error here
});
}
}
}
}
}
}
await App._client.SendAllPhotosAsync(aip);
}
然而,当我尝试将对象添加到列表中时,我得到"尝试读取写保护的内存"错误。 PhotoInspection对象填充了相关数据,在添加到列表之前一切都很好。谢谢你的帮助
答案 0 :(得分:0)
问题是由于Dispatcher.RunAsync
调用引起的,一旦aip.Photos.Add()
lambda 排队,它就会将控制权返回给调用例程,而不是在它完成时。这导致aip
对象在lambda实际运行之前被释放。
MSDN page for CoreDispatcher.RunAsync说:
[...]它在UI线程上安排工作并立即将控制权返回给调用者。
和
要从UI线程中剥离工作线程,请不要使用此方法(CoreDispatcher :: RunAsync)。相反,使用Windows :: System :: Threading :: ThreadPool :: RunAsync方法重载之一。
它还提供了以下代码示例,评论来自Microsoft!
//DO NOT USE THIS CODE.
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await signInDialog.ShowAsync();
});
// Execution continues here before the call to ShowAsync completes.