Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List.add() async task await correct syntax

Hello I am trying to add items to a list asynchronously but I am not sure how it is done and if I am using an incorrect syntax, this is what I have at the moment:

My View:

await viewModel.getMessages();
list.ItemsSource = viewModel.Messages;

My View Model:

public List<Message> Messages { get; set; }

        public async Task getMessages()
        {
            await GetRemoteMessages();
        }

        private async Task GetRemoteMessages()
        {
            var remoteClient = new ChiesiClient();
            var messages = await remoteClient.getMessages().ConfigureAwait(false);
            //App.Database.
            await SaveAll(messages).ConfigureAwait(false);
        }

        public async Task SaveAll(IEnumerable<Message> _messages)
        {
            foreach (var item in _messages)
            {
                await SaveMessage(item);
            }
        }

        public async Task SaveMessage(Message item)
        {
            await Messages.Add(new Message // Cannot await void
            {
                Title = item.Title,
                Description = item.Description,
                Date = item.Date,
                Url = item.Url
            });
        }

I am not sure if I am getting the whole concept right but how can I await adding items to my list? how is the correct way to do this?

like image 832
Mario Galván Avatar asked Dec 14 '22 21:12

Mario Galván


1 Answers

You don't want to add items to a list asynchronously -- there's no real benefit to it.

Your code is fine, you just need to do everything synchronously after you get your messages back from your remote service.

    public List<Message> Messages { get; set; }

    public async Task getMessages()
    {
        await GetRemoteMessages();
    }

    private async Task GetRemoteMessages()
    {
        var remoteClient = new ChiesiClient();
        var messages = await remoteClient.getMessages().ConfigureAwait(false);
        //App.Database.
        SaveAll(messages);
    }

    public void SaveAll(IEnumerable<Message> _messages)
    {
        foreach (var item in _messages)
        {
            SaveMessage(item);
        }
    }

    public void SaveMessage(Message item)
    {
        Messages.Add(new Message // Cannot await void
        {
            Title = item.Title,
            Description = item.Description,
            Date = item.Date,
            Url = item.Url
        });
    }

Now, remoteClient.getMessages() might take a long time! It's an I/O bound task -- it might take a millisecond, or it might take 10 minutes. We don't know, and we can't know. If it actually does end up taking 10 minutes, we don't want the UI to be locked up that entire time. When you use the await keyword, it starts that operation, then gives control back to the UI. When the operation is done, it continues with the rest of the method.

The original example you're working off of saves stuff to a database. That's another I/O bound operation, and thus the database API creators kindly provided you with some asynchronous APIs to help out with that.

You're modifying the example to put the results into a list. Adding to a list is not an I/O bound operation. In fact, it's pretty much instantaneous. As a result, there's no asynchronous API for it. You don't need to do that part asynchronously.

like image 179
Daniel Mann Avatar answered Dec 29 '22 19:12

Daniel Mann