2016-11-29 55 views
2

所以基本上我已經連接好三個文本框,做一個聰明的過濾器,並希望讓用戶做多過濾器。唯一的問題是它發射太頻繁,我想在延遲後發射。 'TextChanged'的事件是有線的基本上運行,我有一個簡單的例子,我想要的:保證方法只觸發一次當事件被觸發的WinForms新方法,多次在.NET 4.5

我有一個簡單的WinForms UI有兩個文本框:「txtWait」和「txtTest」。在前端代碼的屬性是默認和文字是:

txtWait.Text = 1000 
txtTest.Text = "Test Text I have here to look at" 

來測試這一點的方法是剛打退格幾次和等待。我只想只顯示最後一段文字。我只是讓這部分工作,但重置它沒有像我期望的那樣發生。我希望一個人可以擊退退格,退格(僅半秒過去),退格(時鐘重置和新的等待開始)。

而且我後面的代碼是:

Public Class DelayBeforeAction 

    Private _loaded As Boolean = False 
    Private _sw As Stopwatch = New Stopwatch() 

    Public Sub New() 
    InitializeComponent() 
    _loaded = True 
    End Sub 

    Private Sub txtTest_TextChanged(sender As Object, e As EventArgs) Handles txtTest.TextChanged 
    If _loaded Then 
     _sw.Start() 

     DelayExecute(Sub() If _sw.ElapsedMilliseconds > CInt(txtWait.Text) Then _sw.Reset() : MessageBox.Show(txtTest.Text) Else _sw.Reset(), CInt(txtWait.Text)) 
    End If 
    End Sub 

    Private Async Sub DelayExecute(action As Action, timeout As Integer) 
    Await Task.Delay(timeout) 
    action() 
    End Sub 

End Class 
+0

我應該加我沒有添加一個C#標記,它的含義已被刪除,我也接受C#答案。我很擅長在C#或VB.Net中執行代碼。 – djangojazz

+0

如果您使用了一個按鈕,用戶按下以指示「我已完成設置標準」,您不需要延遲。特別是,如果將有多個文本框 – Plutonix

+0

@Plutonix是,這是一個好點,但我也想知道如何做到這一點的只有事件驅動的行爲問題的方式。 – djangojazz

回答

0

具體你的情況,你的第一個txtTest_TextChanged啓動秒錶。你的第二個電話txtTest_TextChanged再次_sw.Start()which has no effect on a running stopwatch

開始已經運行不改變定時器的狀態或重置經過時間特性的秒錶。

時的第一txtTest_TextChanged繼續運行,秒錶的經過時間預計將大於第二:它開始比第二多前,從那以後,所發生的一切是其他嘗試了啓動同一個秒錶。什麼都沒有重置。

也就是說,在這裏使用一個秒錶是根本不可靠,我不建議繼續沿着這條道路。你無法確定你的延續運行的確切時間。

相反,不衡量你是否應該延續可能會被取消,軌道無論取消。

你的具體情況最直接的辦法是在txtTest_TextChanged遞增計數器。如果在繼續執行時計數器沒有被更改,則知道txtTest_TextChanged尚未被第二次調用。

一個更普遍的方式是使用CancellationTokenSource類。大多數基於任務的方法(包括Task.Delay)都有超負荷接受CancellationToken實例。您可以通過CancellationTokenSource.Cancel表明取消申請。

儘管在這種情況下您不需要它,但一般情況下,您也可以在長時間運行的操作期間明確地在特定位置呼叫CancellationToken.ThrowIfCancellationRequested,否則這些操作將不會中止。

+0

如何確定計數器何時使用它,如果它始終增量?你需要參考它需要的東西。如果我只是得到1然後2然後3我怎麼知道什麼號碼使用什麼時候?我做的計時器的原因是爲了這個確切的原因,知道什麼時候第二次通過嘗試。我確實認爲這是不可靠的,因爲它似乎從未在異步操作中正確重啓。取消方法我去了,但沒有一個特定的示例用法,只是在Task.Delay的重載上添加一個取消標記就什麼都不做。 – djangojazz

+0

@djangojazz計數器的基本思想就是'++ this.Counter; var captured = this.Counter; DelayExecute(()=> {if(this.Counter!= captured)return; ...});'。對於取消,你是否真的在最初的'CancellationTokenSource'上調用'CancellationTokenSource.Cancel'來提供你傳遞給'Task.Delay'的'CancellationToken'? *應該*有效果。如果你評論這是不夠的,我可能有一個想法,但我不知道爲什麼它根本無法工作。這就是超載的全部重點。 – hvd