2010-12-02 11 views
7

WinFormsアプリケーションでsetTimeout相当の関数を作成するための簡単なソリューション/アイデア/戦略はありますか?私は主にWeb開発者ですが、これについてWinForms Appでどのようにしたらよいか分かりません。基本的には、テキストボックスがあり、各キーストロークの後に、(自動補完型のような)リストを作成するタスクを実行したいが、ユーザーが文字を入力し続けるとキャンセルできるようにする(例えばclearTimeout)...WinFormsに相当するjavascript setTimeout

唯一の推測は、おそらくBackGroundWorkerを使用して眠っている間にキャンセルすることができます。ユーザーがキー入力をやめてスリープ期間が終了すると、タスクなどが実行されます

(例はC#やVb.Netであれば、私は気にしない)

+0

[C#でのJavascriptののSetTimeout、のsetIntervalと同等てclearInterval](https://stackoverflow.com/questions/40502596/javascripts-settimeout-setinterval-and-clearinterval-equivalent-in-c-sharp/40609390# 40609390) – Koray

答えて

11

あなたはSystem.Timers.Timerを使用することができます。falseに自動リセットを設定し、スタート/ストップ・メソッドを使用して、Elapsedイベントのハンドラを作成します。

11
public void setTimeout(Action TheAction, int Timeout) 
    { 
     Thread t = new Thread(
      () => 
      { 
       Thread.Sleep(Timeout); 
       TheAction.Invoke(); 
      } 
     ); 
     t.Start(); 
    } 
+0

きちんと投稿していただきありがとうございます – davidsleeps

+2

このメソッドの使用はお勧めしません。単一の操作のためだけにスレッド全体を作成しますか?過剰殺戮。他の方法で提供されているTimerクラスを使用すると、より生産的な価値のあるものが得られます。この回答によれば、新しいスレッドごとに1 MBのメモリが割り当てられます。 http://stackoverflow.com/a/2744464/881111 - OPは彼が各キーストロークの後にこれを実行しようとしていたことを覚えています... 1 MBのメモリと各キーストローク用の新しいスレッドを検討してください。悪いアイデア。 – Nuzzolilo

+0

悪い考えだけではありません。これはおそらく並行性の問題を持っています –

17

これは古い質問ですが、代わりの解決方法はTask.Delay(delay).ContinueWith((task) => { /* Code */ });です。

Thread.Sleep vs Task.Delay?

または私はこのための反応性のプログラミングを使用してお勧めしますawait Task.Delay(delay);

https://social.msdn.microsoft.com/Forums/vstudio/en-US/345f0402-3af0-4f96-a501-073674883ba3/building-an-async-settimeout-function?forum=csharpgeneral

+0

それ以来、物事は長い道のりを歩んできました...答えを投稿してくれてありがとう! – davidsleeps

0
public void setTimeout(Action act, int timeout) 
    { 
     Action action =() => 
     { 
      Thread.Sleep(Timeout); 
      act(); 
     }; 

     new Thread(() => Invoke(action)).Start(); 
    } 
+0

これは機能しますか? – theonlygusti

0

があります。 Reactive Extensions for .NETの場合はhttps://github.com/Reactive-Extensions/Rx.NET、Reactiveプログラミングの場合はhttp://reactivex.io/を参照してください。

私は私ではJavaScriptが無効のライブラリを持つ唯一のよく知っているので、私はあなたにC-シャープ例を与えることはできませんが、JavaScriptで、それはこのような何か働くだろうと怖い:

Rx.Observable.fromEvent(..eventdetails..) 
    .debounceTime(300) 
    .distinctUntilChanged() 
    .subscribe(eventHandler); 

をこのような設定を使用すると、オペレータを連鎖させて、すべての種類のイベントをソースからサブスクライバにマップしてマージすることができます。上記の単純な例は、例えばイベントのkeyUpに反応し、300msの間新しいkeyUpがなくなるまで待ってから、新しい値(300ms後)が最後に出力された値と異なる場合に限り、eventHandlerを呼び出します。

0

これは私の方法です.C#7.0の構文機能を使用してください。 タイムアウトアクションが実行されたときにjsと異なるものもあります。

internal static class JsStyleTimeout 
{ 
    private static readonly ConcurrentDictionary<int, Thread> InnerDic; 

    private static int _handle; 

    static JsStyleTimeout() 
    { 
     InnerDic = new ConcurrentDictionary<int, Thread>(); 
    } 

    public static int Set(Action action, int delayMs) 
    { 
     var handle = Interlocked.Increment(ref _handle); 

     var thread = new Thread(new ThreadStart(delegate 
     { 
      Thread.Sleep(delayMs); 
      InnerDic.TryRemove(handle, out var _); 
      Task.Factory.StartNew(action); 
     })); 
     InnerDic.TryAdd(handle, thread); 

     thread.Start(); 
     return handle; 
    } 

    public static void Clear(int handle) 
    { 
     if (InnerDic.TryRemove(handle, out var thread)) 
      thread.Abort(); 
    } 
} 
関連する問題