-1

I am having some issues while using async methods. I am kind of new to it, but I am doing some Blazor code and using Blob storage and some calls need to be async. Here is my code and issue. This code needs to be async because it is getting Blob data from Azure. (FileUpload is my custom object):

        public async Task<List<FileUpload>> GetAllFilesAsync()
        {

            // TODO: GENERATE fileupload objects here and return
            await foreach (var blobItem in _container.GetBlobsAsync())
            {
                var name = blobItem.Name;
                BlobClient blobClient = _container.GetBlobClient(name);

                FileUpload fileUploadViewModel = new FileUpload()
                {
                    FileName = blobItem.Name,
                    FileStorageUrl = blobClient.Uri.ToString(),
                    ContentType = blobItem.Properties.ContentType,
                };

                _allFiles.Add(fileUploadViewModel);

            }
            return _allFiles;
        }

In my Blazor code (Server) I have this code calling the service on initalize:

        private List<FileUpload> fileUploadViewModels = new();

        protected override async Task OnInitializedAsync()
        {
            GetAllBlobsAsync();
        }


        private void GetAllBlobsAsync()
        {
            var allFiles = blobStorageService.GetAllFilesAsync();
             fileUploadViewModels =  allFiles; // This is where the error is thrown
          
        }

Error: Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.List' to 'System.Collections.Generic.List'

I have been searching here and the web and just have not found an answer. I tried Task.FromResult() and others with no luck. As I said, I am kind of new to async and await, so I am hoping I am just missing something small. Can you please clarify what I am doing wrong?

JimboJones
  • 53
  • 13
  • Does this answer your question? [Cannot implicitly convert type 'string' to 'System.Threading.Tasks.Task'](https://stackoverflow.com/questions/14658001/cannot-implicitly-convert-type-string-to-system-threading-tasks-taskstring) – Charlieface May 16 '23 at 13:19

2 Answers2

6

Make the GetAllBlobsAsync method async:

private async Task GetAllBlobsAsync()

So it can internally await the operation:

var allFiles = await blobStorageService.GetAllFilesAsync();

Then await the method itself when calling it:

await GetAllBlobsAsync();

Basically you missed a step in the philosophy of "async all the way down" and were trying to create a synchronous method in the middle of the stack. If at the bottom of the stack there is an async method being awaited, everything up the stack should also be async.

David
  • 208,112
  • 36
  • 198
  • 279
  • Thank you for the explanation, it does help me understand more and I see my mistake. I have changed my code as per your explanation, however, I am still seeing the error I posted on the line below fileUploadViewModels = allFiles; // Conversion error here ' – JimboJones May 16 '23 at 13:06
  • @JimboJones: What is your updated code? Are you sure it's the *exact* same error on the *exact* same line and not a new error? – David May 16 '23 at 13:09
  • sorry about the confusion, I missed the await on this line: var allFiles = await blobStorageService.GetAllFilesAsync(); It is now working! – JimboJones May 16 '23 at 13:15
2

You cannot implicitly convert Task to T because Task is just a job that will settle it Result in future.

So you need to wait for settle. You can do it in a different way.

  1. Convert GetAllBlobsAsync to async and await Task result:
private async Task GetAllBlobsAsync()
{
  var allFiles = await blobStorageService.GetAllFilesAsync();
  fileUploadViewModels =  allFiles;
          
}
  1. Wait for Task to be settle and work with Result:
private void GetAllBlobsAsync()
{
  var task = blobStorageService.GetAllFilesAsync();
  task.Wait();
  var allFiles = task.Result;
  fileUploadViewModels = allFiles;  
}
KAMAEL
  • 175
  • 2
  • 16