簡體   English   中英

異步方法僅在調用MessageDialog時有效

[英]Async method only works when MessageDialog is called

我是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()時才會顯示縮略圖,並且只有在對話框中單擊“確定”按鈕后,縮略圖才會出現。

在沒有await情況下調用thumbnailCallback 這就是未顯示縮略圖的原因(如果幸運的話,您可能會隨機獲得縮略圖:))。 當您放置MessageDialog時,線程有足夠的時間在用戶交互之后執行。

怎么修

如下調用:

await thumbnailCallback(thumbnail, destinationFolder);

建議:

將簽名更改為

public async Task thumbnailCallback(ZipArchiveEntry thumbnail, StorageFolder destinationFolder)

通常,您需要返回Task 主要的例外應該是當您需要具有void返回類型(用於事件)時。

返回void的async方法在另一方面是很特殊的:它們代表頂級async操作,並且在任務返回exception時會起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM