Асинхронный метод работает только при вызове MessageDialog - PullRequest
0 голосов
/ 22 мая 2018

Я очень новичок в 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();
    }

Затем эта задача распаковывает файл, вызывая метод thumbnailCallback после создания ZipArchive.:

 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 (), и он не отображается до тех пор, пока в диалоговом окне не будет нажата кнопка «ОК».

1 Ответ

0 голосов
/ 22 мая 2018

thumbnailCallback вызывается без await.По этой причине thumnail не отображаются (если вам повезет, вы можете получить эскиз в случайном порядке :)).Когда вы помещаете MessageDialog, поток становится достаточно времени для выполнения после взаимодействия с пользователем.

Как исправить

Назовите его так, как показано ниже:

await thumbnailCallback(thumbnail, destinationFolder);

Предложение:

Измените подпись как

public async Task thumbnailCallback(ZipArchiveEntry thumbnail, StorageFolder destinationFolder)

Обычно вы хотите вернуть Task.Основное исключение должно быть, когда вам нужен тип возврата void (для событий).

async методы, которые возвращают void, являются особенными в другом аспекте: они представляют операции верхнего уровня async и имеютдополнительные правила, которые вступают в игру, когда ваша задача возвращает exception.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...