We have a working implementation that is doing I/O operations, returning data from blobs in an async/await manner from Azure Blob Storage. //Method1 is not async, this is what is called from the controllerpublic IEnumerable<Data> Method1(){    //Running the async method and returning the result from task    return Task.Run(() => GetDataAsync()).Result;}private async Task<IEnumerable<Data>> GetDataAsync(){    //There are multiple blob address where the data is held. The code creates, in parallel multiple tasks for each address.    //It returns tasks that will be run in Async pattern    var tasks = multipleBlobAddress.AsParallel.Select(blobAddress =>{            Task<IEnumerable<Data>> task = GetDataFromBlobsAsync(blobAddress);            return task;    });    //Awaits all tasks to complete    var completedTasks = await Task.WhenAll<IEnumerable<Data>>(tasks);    //Selects all the tasks and returns them. Each tasks has data.    return completedTasks.SelectMany(t => t);}private Task<IEnumerable<Data>> GetDataFromBlobsAsync(string address){    //Opens the blob and reads from it    using (var blobStream = blobService.OpenRead(address))    {        //Deserialises the data read from the blob        data = service.DeserialiseData(blobStream);    }    return Task.FromResult<IEnumerable<Data>>(data);}We have understood that the best way to read from blobs is to follow the async/await pattern and not using the AsParallel method (other suggestions are most welcomed). I have the following questions:By creating tasks in parallel and then waiting for all of them to complete, do we lose any performance?What are the obvious areas where we got it wrong or we can improve and potentially increase the performance or make the code better to maintain/read?Are we correctly following the async / await pattern?If you need any extra information about the code, I will happily provide it and hope to make it clearer. 
Downloading blobs asynchronously
c#;async await;azure
There is never a need to do this:return Task.Run(() => GetDataAsync()).Result;Why start a new task and then synchronously wait with .Result? This is the sort of code that will bite you later when you find out that a synchronisation context can cause a deadlock. See Stephen Cleary's blog post on the subject of an async deadlock. Stephen's blog is an absolute gold mine of information on aysnc and await.Either use the synchronous api all the way from your controller down into the Azure Storage SDK or use the asynchronous one (with async and await). Don't mix and match - that's a source of errors and also pointless. Aysnc is useful when there's something else the thread could be doing. E.g. in a web app that's serving requests. If the web app is blocked by .Result or Wait then there is no benefit and you should use the synchronous API.