Асинхронная загрузка в Azure не блокируется даже при вызове Task.WaitAll (задача)

1

Я загружаю файл в Azure. Код загружает файл в порядке, но моя страница обновляется до его завершения и показывает старое изображение. Я могу обновить страницу вручную и отобразить новое изображение. Почему мой метод не ждет завершения задачи?

    public static bool Upload(Stream image, String id)
    {
        try {
            var key = String.Format("{0}.png", id);

            image.Position = 0;

            var container = new CloudBlobContainer(new Uri(string.Format("{0}/{1}", Host, Container)), Credentials);

            var blob = container.GetBlockBlobReference(key);

            blob.Properties.ContentType = "image/png";

            Task task = Task.Run(() => { blob.UploadFromStreamAsync(image); });

            Task.WaitAll(task);
        }
        catch {
            return false;
        }

        return true;
    }

ОТВЕТ: Итак, спасибо aleksey.berezan. Ответ оказался неэффективным.

Итак, это:

Task task = Task.Run(() => { blob.UploadFromStreamAsync(image); });

Task.WaitAll(task);

Стало следующим:

Task.WaitAll(blob.UploadFromStreamAsync(image));

И все сработало отлично!

Теги:
azure
asynchronous
task
blob

2 ответа

5
Лучший ответ

Этот парень:

blob.UploadFromStreamAsync(image);

начинает новую задачу.
Отсюда этот парень:

Task.Run(() => { blob.UploadFromStreamAsync(image); });

просто запускает задачу, которая запускает задачу. Так что этот код:

Task task = Task.Run(() => { blob.UploadFromStreamAsync(image); });

Task.WaitAll(task);

будет просто ждать, пока будет запущена загрузка-задача (что происходит сразу же), но не для завершения загрузки-задачи.

Чтобы исправить ситуацию, вам придется написать:

Task.WaitAll(blob.UploadFromStreamAsync(image));
  • 0
    Просто вопрос: есть ли какая-то разница, если кто-то вызывает Task.WaitAll(blob.UploadFromStreamAsync(stream)) по сравнению с синхронным вызовом blob.UploadFromStream(stream) ? Я имею в виду, потому что мы ожидаем, что в текущем потоке завершится другой поток ... Таким образом, текущий поток не освобождается в пул потоков, так как в этом коде нет асинхронного / ожидающего выполнения ... Итак, в основном, как я вижу, оба вызова идентичны.
  • 0
    На моей машине (win8 / net45 / x64) этот парень blob.UploadFromStream(image); работает в текущем потоке, но этот Task.WaitAll(blob.UploadFromStreamAsync(image)); запускает операцию в другом потоке и ждет завершения в текущем. Таким образом, в обоих случаях текущий поток занят до завершения операции, но во втором задействован дополнительный поток для фактической операции.
Показать ещё 1 комментарий
2

Вы ожидаете, что задача Task.Run с Task.Run. Вы хотите подождать UploadFromStreamAsync. На самом деле я не понимаю, зачем вам нужна Task.Run здесь. Это только замедляет работу. Вы передаете работу в пул потоков, а затем дождитесь ее завершения.

Просто позвоните в синхронную версию UploadFromStreamAsync если она есть. Или вызовите " Wait над задачей, UploadFromStreamAsync возвращает UploadFromStreamAsync (менее предпочтительно).

Возможно, вы захотите пересмотреть обработку исключений. Вы никогда не узнаете об ошибках в этом методе, потому что все исключения выбрасываются.

  • 0
    Обработка исключений была только временной сделкой. Я еще не полностью реализовал метод. И просто вызов UploadFromStreamAsync тоже не сработал. Но вызов Task.WaitAll (UploadFromStreamAsync) сработал.
  • 0
    Вам лучше просто вызвать синхронную версию напрямую. Если это невозможно, вызовите Wait для задачи, а не Task.WaitAll что излишне сложно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню