2

ユーザーが入力したテキスト フィールドの入力を検証したいと考えています。この機能は正常に動作しますが、外部 API にヒットしているため、検証のレートを制限したいと考えています。ユーザーが 750 ミリ秒入力しなかった場合にのみ検証を実行したいと思います。

ATM 私は単にこれを使用しています:

private void Configure_Load(object sender, EventArgs e)
{
    endpointBox.KeyUp += EndpointBox_KeyUp;
}

void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
    TestHTTP200(endpointBox.Text);
}
4

3 に答える 3

1

JavaScript の SetTimeout メソッドと同等のメソッドが必要です。これは、ユーザーがさらに入力を提供するとキャンセルできます。

ここから取られたコード。

    public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
    {
        System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
        timer.Elapsed += (source, e) =>
        {
            method();
        };

        timer.AutoReset = false;
        timer.Enabled = true;
        timer.Start();

        // Returns a stop handle which can be used for stopping
        // the timer, if required
        return timer as IDisposable;
    }

次に、これをキーアップ ハンドラーで使用できます。

    void EndpointBox_KeyUp(object sender, KeyEventArgs e) 
    {
         IDisposable timeout = SetTimeout(() => TestHTTP200(endpointBox.Text), 750);
         if (this.currentTimeout != null) {
             this.currentTimeout.Dispose();
             this.currentTimeout = timeout;
         }
    }

これは少なくとも基本的な原則です。ユーザーが入力するたびに、750 ミリ秒のタイムアウトを再開して、保留中のタイマーをキャンセルします。

更新: 完全なコード サンプル:

public partial class Form1 : Form
{
    private IDisposable currentTimeout;

    public Form1()
    {
        InitializeComponent();
    }

    private void EndpointBox_KeyUp(object sender, KeyEventArgs e)
    {
        IDisposable timeout = TimerHelper.SetTimeout(() => TestHTTP200(EndpointBox.Text), 750);
        if (this.currentTimeout != null)
        {
            this.currentTimeout.Dispose();
            this.currentTimeout = timeout;
        }
    }

    private void TestHTTP200(string text)
    {
        //...
    }
}

public class TimerHelper
{
    public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
    {
        System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
        timer.Elapsed += (source, e) =>
        {
            method();
        };

        timer.AutoReset = false;
        timer.Enabled = true;
        timer.Start();

        // Returns a stop handle which can be used for stopping
        // the timer, if required
        return timer as IDisposable;
    }
}
于 2013-05-12T12:36:03.213 に答える
0
using System;

namespace Azine_Library.Misc
{

    /// <summary>
    /// Represents a way to delay something, eg. something an event handler does, update-ion of a control, object or to run a method, This class '<see cref="DelayUpdate"/>'
    /// is intended to be used as a delayer of some sort and contains an event, '<see cref="PushUpdate"/>' that would be subcribed to an event handler where then the code 
    /// intended to be delayed would go. This object also contains a method, '<see cref="delay"/>' that when called delays the code written/located within the event handler 
    /// that is handling the '<see cref="PushUpdate"/>' event. The method, <see cref="delay"/> should be called from an event handler or a method of some sort that would orginally 
    /// execute the code written/located within the event handler described above also. An example of how this object can interact with another object is described and documented in great detail
    /// within the documentation for "Azine_Library", also an example program is available with the documentation.
    /// </summary>
    public class DelayUpdate
    {
        // Written, 17.06.2017

        #region Fields / Properties

        /// <summary>
        /// Occurs when the provided time (interval:) has elapsed
        /// </summary>
        public event EventHandler PushUpdate;
        /// <summary>
        /// READONLY. the amount of times the timer has ticked since the last call to delay, (DelayUpdate.delay).
        /// </summary>
        public int updateCounter
        {
            get;
            private set;
        }
        /// <summary>
        /// The amount of time [this] waits for until it pushes the update. (Milliseconds). default value: '500'.
        /// </summary>
        public int interval
        {
            get;
            set;
        }
        /// <summary>
        /// Holds the amount of times [this] raises the "DelayUpate.PushUpdate" event every call to DelayUpdate.delay() method. default value: '1'.
        /// </summary>
        public int updatesPerPush
        {
            get;
            set;
        }

        private System.Diagnostics.Stopwatch stopWatch;
        private System.Windows.Forms.Timer timer;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of type, 'DelayUpdate'; sets the classes' properties to the defaults.
        /// </summary>
        public DelayUpdate()
        {
            //Initializing Variables
            this.updateCounter = 0;
            this.interval = 500;
            this.updatesPerPush = 1;
            this.stopWatch = new System.Diagnostics.Stopwatch();
            this.timer = new System.Windows.Forms.Timer();

            //Sub-ing Events
            this.timer.Tick += this.Timer_Tick;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Delays the raising of the event, PushUpdate; call this method when a property of an object has changed. eg, TextBox.TextChanged => DelayUpdate.delay();
        /// </summary>
        public void delay()
        {
            // Written, 13.06.2017

            this.timer.Start();
            this.stopWatch.Restart();
            this.updateCounter = 0;
        }

        #endregion

        #region Events

        /// <summary>
        /// Raises the 'DelayUpdate.PushUpdate' event.
        /// </summary>
        private void onPushUpdate()
        {
            //Written, 26.05.2017 : 5:22pm

            if (PushUpdate != null)
                PushUpdate.Invoke(this, new EventArgs());
        }

        #endregion

        #region Event Handlers

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Written, 13.06.2017

            if (this.stopWatch.ElapsedMilliseconds > this.interval)
            {
                if (this.updateCounter < this.updatesPerPush)
                {
                    this.timer.Stop();
                    this.onPushUpdate();
                }
                this.updateCounter++;
            }
        }

        #endregion
    }
}

そして、これはあなたがこのクラスをどのように使用するかですDelayUpdate.cs:

「search_textBox」という名前のテキストボックスがあり、textChanged イベントハンドラーが添付されているファイルのディレクトリを検索する WinForm があるとします。

namespace DelayUpdateExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.search_textBox.TextChanged += this.Search_textBox_TextChanged;
        }

        private void Search_textBox_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

クラスへの参照を作成し、DelayUpdate.cs初期化します。DelayUpdate.PushUpdate次のようにイベントにサブスクライブします。

private DelayUpdate delayUpdate;

        public Form1()
        {
            InitializeComponent();

            this.delayUpdate = new DelayUpdate()
            {
                interval = 500,
                updatesPerPush = 1,
            };
            this.delayUpdate.PushUpdate += this.DelayUpdate_PushUpdate;

            this.search_textBox.TextChanged += this.Search_textBox_TextChanged;
        }

        private void DelayUpdate_PushUpdate(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

textChanged イベント ハンドラー内で、DelayUpdate.delay()like so. を呼び出します。

private void Search_textBox_TextChanged(object sender, EventArgs e)
{
    this.delayUpdate.delay();
}

そして、遅延させたいコードは、DelayUpdate_PushUpdate(object, EventArgs)購読している に移動します。そのようです:

    private void DelayUpdate_PushUpdate(object sender, EventArgs e)
    {
        // You would search the directory here..
        // Code that you want to delay would go here.
    }
于 2018-06-19T02:37:10.413 に答える