触发一个动作在X毫秒后开始

本文关键字:开始 一个 | 更新日期: 2023-09-27 18:16:49

我正在开发一个Xamarin Forms移动应用程序,它有一个包含搜索栏、ListView和地图控件的页面。列表视图包含一个地址列表,这些地址在地图上作为引脚反映。

当用户在SearchBar中键入时,ListView会自动更新(通过ViewModel绑定)。为列表过滤数据源的ViewModel方法看起来像这样…

void FilterList()
{
    listDataSource = new ObservableCollection<location>(
        locationData.Where(l => l.Address.Contains(searchBar.Text))
    );
    // ***** Now, update the map pins using the data in listDataSource
}

我想在ListView被过滤时更新Map,但不是在每次按键上,因为这可能在一秒钟内发生多次。实际上,我希望在Map更新之前,在每个FilterList事件中都有一个"滚动暂停"。在伪代码…

    // ***** Now, update the map pins using the data in listDataSource
    if (a previously-requested map update is pending)
    {
        // Cancel the pending map update request
    }
    // Request a new map update in 1000ms using [listDataSource]

可以使用Stopwatch类来完成此操作,该类可在可移植类库中获得,但我怀疑使用Tasks有更干净/更好的方法来完成此操作。

谁能建议一个"更聪明"的 pcl兼容方法来做到这一点?

触发一个动作在X毫秒后开始

你可以试试:

await Task.Delay(2000);

就像你说的,这可以通过使用Tasks和异步编程以一种非常干净的方式完成。

你会想要阅读它:http://msdn.microsoft.com/en-us/library/hh191443.aspx

下面是一个例子:

public async Task DelayActionAsync(int delay, Action action) 
{
    await Task.Delay(delay);
    action();
}

这是我所做的,它在我的Xamarin Form应用程序中工作。

    public string Search
    {
        get { return _search; }
        set
        {
            if (_search == value)
                return;
            _search = value;
            triggerSearch = false;
            Task.Run(async () =>
            {
                string searchText = _search;
                await Task.Delay(2000);
                if (_search == searchText)
                {
                    await ActionToFilter();
                }
            });
        }
    }

我已经将这个'Search'属性绑定到我的Entry字段。每当用户过滤某些内容时,代码等待1秒,然后将新的Text字段与1秒前的字段进行比较。假设字符串相等意味着用户已经停止输入文本,现在可以触发代码进行过滤。

简单延迟的问题是,当延迟过期时,您可能会获得一堆事件排队。您可以添加逻辑来丢弃在延迟运行时引发的事件。如果你想在更高的层次上声明逻辑,你可以使用响应式扩展。

运行在最新的xamarin版本中

另一个点击按钮的好方法是

    public async void OnButtonClickHandler(Object sender, EventArgs e)
{
    try
    {
        //ShowProgresBar("Loading...");
        await Task.Run(() =>
        {
            Task.Delay(2000); //wait for two seconds
            //TODO Your Business logic goes here
            //HideProgressBar();
        });
        await DisplayAlert("Title", "Delayed for two seconds", "Okay");
    }
    catch (Exception ex)
    {
    }
}

asyncawait键很重要,假设您在多线程环境下工作。