List.add()异步任务等待的正确语法。

4

你好,我正在尝试异步地向列表中添加项目,但我不确定该如何实现,也不知道是否使用了不正确的语法。目前我的代码如下:

视图模板:

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

我的视图模型:

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
            });
        }

我不确定自己是否完全理解了概念,但是我如何等待添加项目到我的列表中?正确的操作方式是什么?


1
这没有意义。为什么你想要等待将新项目添加到列表中? - Selman Genç
你可能想要研究一下TPLRX这样的东西。我不确定它们在Xamarin中的兼容性如何,但我有印象Xamarin的覆盖范围相当不错,所以这应该不是问题。 - Matthew Haugen
1
将项目添加到列表中并不是一个需要异步执行才能获得任何好处的任务。 - Daniel Mann
@Selman22 我需要等待Web服务完成才能呈现我的列表视图,但如果我没有这些项目,那么就没有什么可以呈现的了,你明白我的意思吗? - Mario Galván
我正在使用Rob Gibbens的这篇文章http://arteksoftware.com/end-to-end-mvvm-with-xamarin/,但我想使用结构体而不是本地数据库。 - Mario Galván
显示剩余2条评论
1个回答

13

你不需要异步地向列表中添加项目——这样做没有实际的好处。

你的代码没问题,只需要在从远程服务获取消息后同步执行所有操作即可。

    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
        });
    }

现在,remoteClient.getMessages() 可能需要很长时间!这是一个I/O绑定任务--可能需要一毫秒,也可能需要10分钟。我们不知道,也无法知道。如果它实际上需要花费10分钟,我们不希望UI在整个时间内被锁定。当您使用 await 关键字时,它会启动该操作,然后将控制权返回给UI。当操作完成后,它会继续执行方法的其余部分。

您要修改的原始示例将内容保存到数据库中。这是另一个I/O绑定的操作,因此数据库API创建者提供了一些异步API来帮助处理。

您正在修改示例将结果放入列表中。向列表添加内容并不是I/O绑定操作。事实上,它几乎是瞬间完成的。因此,没有异步API可用于此操作。您不需要将其异步执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接