C# 延迟后触发动作

C# 延迟后触发动作,c#,async-await,xamarin.forms,C#,Async Await,Xamarin.forms,我在Xamarin.Forms项目的ContextChanged事件中有以下代码: async void OnTextChanged(object sender, TextChangedEventArgs e) { if (this.txtClientFilter.Text.Length > 4) { var client_list= App.ClientManager.GetTasksAsy

我在Xamarin.Forms项目的ContextChanged事件中有以下代码:

async void OnTextChanged(object sender, TextChangedEventArgs e)
        {

            if (this.txtClientFilter.Text.Length > 4)
            {
                var client_list= App.ClientManager.GetTasksAsync(txtClientFilter.Text);
                var template = new DataTemplate(typeof(TextCell));

                template.SetBinding(TextCell.DetailProperty, "nom_ct");
                template.SetBinding(TextCell.TextProperty, "cod_ct");

                listview.ItemTemplate = template;
                listview.ItemsSource = await client_list;

            }
        }
如您所见,几乎每个按键都试图发出请求(通过GetTaskAsync方法)。我不想每按一次键,我想忽略1000毫秒以下的一些键

我该怎么做?我发现了一些使用Task.Delay()的示例,但没有按预期工作

    private int taskId = 0;

    private async void ExecAutoComplete()
    {
        var client_list = App.ClientManager.GetTasksAsync(txtClientFilter.Text);
        var template = new DataTemplate(typeof(TextCell));

        template.SetBinding(TextCell.DetailProperty, "nom_ct");
        template.SetBinding(TextCell.TextProperty, "cod_ct");

        listview.ItemTemplate = template;
        listview.ItemsSource = await client_list;
    }

    private void TryExecute(int taskId)
    {
        if (this.taskId == taskId)
            this.Invoke((MethodInvoker)(ExecAutoComplete));
    }

    private async void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        ++taskId;
        Task.Delay(1000).ContinueWith(t =>  TryExecute(taskId));
    }
我们在每个
textChange
上创建唯一的
taskId
,如果1000毫秒后
taskId
保持不变(不再有文本更改),我们执行实际调用


我们在每个
textChange
上创建唯一的
taskId
,如果在1000ms之后
taskId
保持不变(不再有文本更改),我们将执行实际调用。

在页面上创建
\u lastClickTime
类型的
私有属性,并将其添加到按钮单击处理程序的开头:

if (DateTime.Now - _lastClickTime < new TimeSpan(0, 0, 0, 0, 1000))
{
    return;
}
_lastClickTime = DateTime.Now;
if(DateTime.Now-\u lastClickTime

我是否误解了您的问题?

在页面上创建一个
\u lastClickTime
类型为
DateTime
的私有属性,并将其添加到按钮单击处理程序的开头:

if (DateTime.Now - _lastClickTime < new TimeSpan(0, 0, 0, 0, 1000))
{
    return;
}
_lastClickTime = DateTime.Now;
if(DateTime.Now-\u lastClickTime


我是否误解了您的问题?

使用任务。使用CancellationToken延迟,并在每次拨打新电话之前取消旧电话。这样,只有1000毫秒后的最后一次按键才会被执行。很难看出您尝试了什么并且“没有按预期工作”,但也许您应该查看TimeSpan上的比较运算符,看看自上次调用以来有多长时间……一旦开发人员开始讨论这样的基于时间的需求,我建议研究无功扩展(Rx)。它有一个陡峭的学习曲线,但对于这类问题非常适合。使用Task。使用CancellationToken延迟,并在每次打新电话之前取消旧电话。这样,只有1000毫秒后的最后一次按键才会被执行。很难看出您尝试了什么并且“没有按预期工作”,但也许您应该查看TimeSpan上的比较运算符,看看自上次调用以来有多长时间……一旦开发人员开始讨论这样的基于时间的需求,我建议研究无功扩展(Rx)。它有一个陡峭的学习曲线,但对于这类问题来说是完美的。旁注:为什么你把
async
ContinueWith
(短到让人困惑)?好的一点,我只是把OP
async
放在那里,因为他的其他代码可能依赖它。在快速按键之后,我得到了这个例外:(Excepción de HRESULT:0x8001010E(RPC_E_error_THREAD))哦,对了,我们不能从另一个线程更新UI。我刚刚更新了TryExecute方法来在UI线程上运行UI更新。再试一次。如果您使用了
等待任务。延迟(1000);TryExecute(taskId);
(我认为@AlexeiLevenkov想到的),不会有线程问题。旁注:为什么要混合使用
async
ContinueWith
(短到让人困惑)?好的一点,我只是在那里保留了OP
async
,因为他的其他代码可能依赖它。快速按键后,我得到了这个异常:(例外情况:0x8001010E(RPC\E\u错误线程))哦,对了,我们不能从另一个线程更新UI。我刚刚更新了TryExecute方法来在UI线程上运行UI更新。再试一次。如果您使用了
等待任务。延迟(1000);TryExecute(taskId);
(我认为@AlexeiLevenkov想到的),将不会出现线程问题。如果两次按键快速发生,您的逻辑将只执行第一次而不执行第二次。而OP需要相反的逻辑-第一次按键被忽略,而第二次按键被执行。如果两次按键快速发生,您的逻辑将只执行第一次按键,而不执行第二次按键。而OP需要相反的逻辑-第一次按键被忽略在执行第二个时忽略。