【发布时间】:2018-05-22 16:35:14
【问题描述】:
我对 C# 非常陌生,但仍在尝试了解异步方法的工作原理。我的 UWP 应用需要在将压缩文件夹拖放到屏幕上时从压缩文件夹中检索 JPG 缩略图,在文件夹上传时显示带有进度环的缩略图,然后在上传完成后移除进度环。
首先当用户删除文件时触发此方法:
private async void OnFileDrop(object sender, DragEventArgs e)
{
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var items = await e.DataView.GetStorageItemsAsync();
if (items.Count > 0)
{
foreach (var appFile in items.OfType<StorageFile>())
{
StorageFolder downloadFolder = ApplicationData.Current.LocalFolder;
StorageFolder unzipFolder =
await downloadFolder.CreateFolderAsync(Path.GetFileNameWithoutExtension(appFile.Name),
CreationCollisionOption.GenerateUniqueName);
await UnZipFileAsync(appFile, unzipFolder);
}
}
}
下一步:
public static IAsyncAction UnZipFileAsync(StorageFile zipFile, StorageFolder destinationFolder, Action<ZipArchiveEntry, StorageFolder> callback, Action<ZipArchiveEntry> completeCallback)
{
return UnZipFileHelper(zipFile, destinationFolder, thumbnailCallback, completeCallback).AsAsyncAction();
}
然后此任务解压缩文件,在创建 ZipArchive 后调用 thumbnailCallback 方法:
private static async Task UnZipFileHelper(StorageFile zipFile, StorageFolder destinationFolder, Action<ZipArchiveEntry, StorageFolder> thumbnailCallback, Action<ZipArchiveEntry> completeCallback)
{
if (zipFile == null || destinationFolder == null ||
!Path.GetExtension(zipFile.Name).Equals(".zip", StringComparison.OrdinalIgnoreCase)
)
{
throw new ArgumentException("Invalid argument...");
}
Stream zipMemoryStream = await zipFile.OpenStreamForReadAsync();
// Create zip archive to access compressed files in memory stream
using (ZipArchive zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
{
ZipArchiveEntry thumbnail = zipArchive.GetEntry("thumbnail.jpg");
thumbnailCallback(thumbnail, destinationFolder);
// Unzip compressed file iteratively.
foreach (ZipArchiveEntry entry in zipArchive.Entries)
{
await UnzipZipArchiveEntryAsync(entry, entry.FullName, destinationFolder);
}
}
}
这是 thumbnailCallback 方法,应该在上传文件夹时显示缩略图:
public async void thumbnailCallback(ZipArchiveEntry thumbnail, StorageFolder destinationFolder)
{
// thumbnail only displays after this has been called and user clicks OK button to close dialog
var messageDialog = new MessageDialog("displaying thumbnail");
await messageDialog.ShowAsync();
// code to display thumbnail
Canvas canvas = new Canvas();
canvas.Width = 200;
canvas.Height = 125;
ProgressRing progressRing = new ProgressRing();
progressRing.Name = thumbnail.FullName;
progressRing.IsActive = true;
progressRing.Height = 50;
progressRing.Width = 50;
Canvas.SetTop(progressRing, 35);
Canvas.SetLeft(progressRing, 75);
Canvas.SetZIndex(progressRing, 2);
Image thumb = new Image();
thumb.Name = thumbnail.FullName;
thumb.Width = 200;
thumb.Height = 125;
thumb.Opacity = 0.2;
BitmapImage bitmapImage = new BitmapImage();
Uri uri = new Uri(destinationFolder.Path + "\\" + thumbnail.FullName);
bitmapImage.UriSource = uri;
thumb.Source = bitmapImage;
canvas.Children.Add(thumb);
canvas.Children.Add(progressRing);
}
目前缩略图仅在首先调用 MessageDialog.ShowAsync() 时才会显示,并且在单击对话框上的 OK 按钮之前不会显示。
【问题讨论】:
-
如果显示缩略图的代码在
await之后,那么您看到的行为是预期的。在调用ShowAsync之前移动代码以显示缩略图。 -
我明白,问题是我根本不希望 MessageDialog 出现,但如果我删除它,其余代码将不起作用。
-
如果您删除消息对话框,程序是否结束?
-
@jdweng 不,它会继续上传文件夹,只是上传时不显示缩略图。
-
现在您的原始代码无法编译,所以很难说,
UnZipFileHelper使用的参数数量不匹配。您可以完全从thumbnailCallback中删除async和ShowDialogAsync。如果这不起作用,我们需要查看用于显示缩略图的代码。
标签: c# uwp async-await