触发在X毫秒后启动的操作

时间:2014-08-07 07:25:52

标签: c# mvvm task-parallel-library portable-class-library xamarin.forms

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

当用户在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
}

我希望更新Map,因为ListView已经过滤,但不是每次按键都会更新,因为这可能会每秒发生多次。基本上,我想在更新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]

可以使用可移植类库中提供的秒表类来完成此操作,但我怀疑使用任务可以实现更清晰/更好的方法。

有人可以建议“聪明” PCL兼容这样做吗?

6 个答案:

答案 0 :(得分:17)

你可以尝试:

await Task.Delay(2000);

答案 1 :(得分:9)

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

您需要了解它:http://msdn.microsoft.com/en-us/library/hh191443.aspx

以下是一个例子:

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

    action();
}

答案 2 :(得分:9)

以下是我所做的,它可以在我的Xamarin表单应用中使用。

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

我是这样的搜索&#39;绑定到我的输入字段的属性。每当用户过滤某些内容时,代码等待1秒钟,然后将新的文本字段与之前1秒之前的字段进行比较。假设字符串相等意味着用户已停止输入文本,现在可以触发代码进行过滤。

答案 3 :(得分:1)

使用最新的xamarin版本。

按钮点击的另一种很棒的方法是,

    public async void OnButtonClickHandler(Object sender, EventArgs e)
{
    try
    {
        //ShowProgresBar("Loading...");

        await Task.Run(() =>
        {
            Task.Delay(2000); //wait for two milli seconds

            //TODO Your Business logic goes here
            //HideProgressBar();

        });

        await DisplayAlert("Title", "Delayed for two seconds", "Okay");

    }
    catch (Exception ex)
    {

    }
}

asyncawait密钥很重要,假设您正在处理多线程环境。

答案 4 :(得分:1)

简单延迟的问题在于,当延迟到期时,您可以排队等待一堆事件。您可以添加逻辑以丢弃在延迟运行时引发的事件。如果要在更高级别上声明逻辑,则可以使用Reactive Extensions

答案 5 :(得分:0)

another种方式:

new Handler().PostDelayed(() =>
{
    // hey, I'll run after 1000 ms
}, 1000);

当然您也可以使用以下版本:

var handler = new Handler();
var action = () => 
{
    // hey, I'll run after 1000 ms
};

handler.PostDelayed(action, 1000);