一劳永逸地创建异步请求执行

时间:2019-04-04 16:06:06

标签: c# asynchronous async-await

我正在尝试通过一种“开火”机制将文件上传到云。但是只要处理完所有文件,其他操作便会感兴趣(成功/失败不会有所作为)。

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 :(得分:0)

这里要注意的一件事,异步!=新线程。

您的同步上下文决定了异步方法将在哪个线程上执行,以及是否将使用新线程。

如果您想要可预测的并行执行,则可以执行Task.Run在新线程上运行任务。

答案 1 :(得分:0)

由于您不公开运行时,因此我假设运行时带有SynchronizationContext

在同步上下文中,连续性将始终被发布到序列化这些连续性。

为避免这种情况,请在所有不应在同步上下文中继续使用的ConfigureAwait(false)上使用await