Создание асинхронного выполнения запроса в огне и забыть о моде - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь осуществить загрузку файлов в облако с помощью своего рода механизма запуска и забывания. Но было бы просто интересно какое-то другое действие после обработки всех файлов (успех / неудача не имеет значения).

public async void OuterMethodAsync(List<BlobFile> files)
{
    List<Task> uploadTasks = new List<Task>();
    foreach(var uploadFile in files)
    {
        Task uploadTask = UploadToCloudAsync();
        uploadTasks.Add(uploadTask);
    }

    //Some sync logic unrelated to above tasks

    //awaiter
    Debug.WriteLine("Before Await");
    await Task.WhenAll(uploadTasks);
    Debug.WriteLine("After Await");

    SomeOtherSyncMethodPostAwait();
}

public async Task UploadToCloudAsync()
{
    Debug.WriteLine("Before Upload");
    //Upload to blob logic
    Debug.WriteLine("After Upload");
}

В этом случае для сценария из 3 файлов я ожидал увидеть что-то вроде: 1. Перед загрузкой 1 2. Перед загрузкой 2 3. После загрузки 1 4. Перед загрузкой 3 5. Прежде чем ждать 6. После ожидания 2 (или 3 в зависимости от того, что быстрее) 7. После ожидания 3 (или 2 в зависимости от того, что медленнее) 8. После ожидания

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

Также вызывающая сторона моего OutMethodAsync не ожидает возврата этого метода. В каком случае это должно бежать как огонь и забыть Но, учитывая, что он работает синхронно, мое предположение является ожидающим или нет, OuterMethodAsync также будет синхронным?

Ответы [ 2 ]

0 голосов
/ 07 апреля 2019

Поскольку вы не раскрываете время выполнения, я предполагаю, что оно будет иметь SynchronizationContext.

В контексте синхронизации в него всегда будут публиковаться продолжения, сериализующие эти продолжения.

Чтобы избежать этого, используйте ConfigureAwait(false) на всех await, которые не должны продолжаться в контексте синхронизации.

0 голосов
/ 04 апреля 2019

Здесь следует отметить одну ключевую вещь: async! = New thread.

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

Если вы хотите предсказуемое параллельное выполнение, тогда вы можете выполнить Task.Run для запусказадание в новой теме.

...