1. 程式人生 > 其它 >.NET 多執行緒開發總結(四)——藉助非同步語法實現可延時觸發的按鈕

.NET 多執行緒開發總結(四)——藉助非同步語法實現可延時觸發的按鈕

技術標籤:C#WPF

轉眼又是一年,作為開年的第一篇部落格,先寫點簡單的熱熱手,畢竟也好久沒寫了。

如題,這是一篇實戰型別的文章,之所以放到“多執行緒開發”這個系列來呢,是因為…Emmmm,沒有理由,就是想放這(任性**_**)。

進入正題>>>

在日常開發中,會遇到如下一些情況:
①按鈕點選後隔一段時間方可再次點選,如:傳送驗證碼
②按鈕載入後隔一段時間方可點選,如:閱讀條款後已同意按鈕
③按鈕點選後隔一段時間才會觸發事件,如:點選查詢按鈕後指定時間無響應則主動結束

針對①②兩種情況,我們可以聯合起來分析,如在Click事件或Load事件觸發後禁用按鈕一段時間即可。這段程式碼非常簡單,非常符合此篇部落格的主題。

public async void DelayToEnable(int milliseconds)
{
    this.IsEnabled = false;
    await Task.Delay(milliseconds);
    this.IsEnabled = true;
}

針對第③種情況,原本也可以用以上方法進行稍作調整來實現,但為了體現封裝性,也方便日後使用,所以還是繼承Button重寫了一些東西。

public class DelayButton : System.Windows.Controls.Button
{
	/// <summary>
    /// 延時啟用
/// </summary> /// <param name="milliseconds"></param> public async void DelayToEnable(int milliseconds) { this.IsEnabled = false; await Task.Delay(milliseconds); this.IsEnabled = true; } /// <summary> /// 取消延時觸發的令牌 /// </summary>
private CancellationTokenSource m_DelayTriggerCts; /// <summary> /// 延時觸發間隔,單位(ms) /// </summary> public int DelayTriggerInterval { get { return (int)GetValue(DelayTriggerIntervalProperty); } set { SetValue(DelayTriggerIntervalProperty, value); } } // Using a DependencyProperty as the backing store for DelayTriggerInterval. This enables animation, styling, binding, etc... public static readonly DependencyProperty DelayTriggerIntervalProperty = DependencyProperty.Register(nameof(DelayTriggerInterval), typeof(int), typeof(DelayButton), new PropertyMetadata(0)); /// <summary> /// 延時觸發路由事件 /// </summary> public static readonly RoutedEvent DelayTriggerRoutedEvent = EventManager.RegisterRoutedEvent("DelayTrigger", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(DelayButton)); public event RoutedEventHandler DelayTrigger { add { this.AddHandler(DelayTriggerRoutedEvent, value); } remove { this.RemoveHandler(DelayTriggerRoutedEvent, value); } } /// <summary> /// 取消延時觸發 /// </summary> public void CancelDelayTrigger() { m_DelayTriggerCts?.Cancel(); } protected override async void OnClick() { base.OnClick(); try { m_DelayTriggerCts = new CancellationTokenSource(); await Task.Delay(DelayTriggerInterval, m_DelayTriggerCts.Token); RoutedEventArgs args = new RoutedEventArgs(DelayTriggerRoutedEvent, this); this.RaiseEvent(args); } catch (Exception) { Console.WriteLine("The delay trigger has been cancelled."); } finally { m_DelayTriggerCts.Dispose(); m_DelayTriggerCts = null; } } }

(增加一個可以手動取消延遲的令牌,可以在長時間的延遲等待過程中隨時結束)

上一篇:.NET 多執行緒開發總結(三)——執行緒間的訊號傳遞(執行緒互動)