2010-12-02 27 views
7

Bir WinForms uygulamasında setTimeout eşdeğer işlevi oluşturmak için basit bir çözüm/fikir/strateji var mı. Öncelikle bir web geliştiricisiyim, ancak bir WinForms uygulamasında bunu nasıl yapacağımı bilmiyorum. Temel olarak, bir metin kutum var ve her tuşa basıldıktan sonra, bir listeyi doldurmak için bir görev çalıştırmak istiyorum (otomatik tamamlama türü bir şey gibi) ancak kullanıcı karakterleri girmeye devam ederse iptal edebilir (örn. ClearTimeout).Winforms javascript setTimeout eşdeğeri

Belki de bir BackGroundWorker'ı kullanıp başlangıçta uyumaya çalışıyorum ve uyurken, kullanıcı anahtarlar girmeyi durdurur ve uyku süresi biterse iptal edilebilir, sonra gider ve görevi çalıştırır.

(örnek C# veya Vb.Net eğer umrumda değil)

+0

[JavaScript'ın setTimeout, SetInterval ve clearInterval C# eşdeğer] (https://stackoverflow.com/questions/40502596/javascripts-settimeout-setinterval-and-clearinterval-equivalent-in-c-sharp/40609390# 40609390) – Koray

cevap

11

bir System.Timers.Timer kullanabilirsiniz: false olarak ayarlanır Autoreset ve Başlat/Durdur yöntemleri kullanmak ve Geçen olay için bir işleyici oluşturun.

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

Temiz bir çözüm göndermek için teşekkürler – davidsleeps

+2

Bu yöntemi kullanmanız tavsiye etmem. Sadece tek bir işlem için tam bir iplik oluşturma? Overkill. Daha fazla üretim değeri olan bir şey için diğer yöntemde sağlanan Timer sınıfını kullanın. Bu cevaba göre, her yeni konu için 1 MB bellek ayrılmıştır. http://stackoverflow.com/a/2744464/881111 - Unutmayın, OP her tuşa basıldıktan sonra bunu çalıştıracağını söyledi ... böylece 1 MB bellek ve her tuş vuruşu için yeni bir konu göz önünde bulundurun. Kötü bir fikir. – Nuzzolilo

+0

Sadece kötü bir fikir değil. Muhtemelen eşzamanlılık sorunları var –

17

Bu eski bir soru olduğunu biliyorum ama alternatif bir çözüm Task.Delay(delay).ContinueWith((task) => { /* Code */ }); kullanmak olacaktır.

Thread.Sleep vs Task.Delay?

veya bunun için reaktif programlama kullanarak öneriyoruz 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

Şeyler o zamandan beri uzun bir yol geldi ... cevabı göndermek için teşekkürler! – davidsleeps

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

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

Bu işe yarıyor mu? – theonlygusti

0

yoktur. Reaktif Programlama hakkında genel bilgi için .NET için Reaktif Uzantılar ve http://reactivex.io/ için bkz. https://github.com/Reactive-Extensions/Rx.NET.

ben JavaScript reaktif kütüphane ile sadece aşinayım korkuyorum, yani sana bir C-Sharp örnek vermek olamaz, ama JavaScript böyle bir şey çalışmak istiyorum:

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

Bu şekilde bir kurulum kullanarak, zincir operatörlerini bir kaynaktan bir aboneye kadar her türlü olayı eşleştirmek ve birleştirmek için zincirleme yapabilirsiniz. Yukarıdaki basit örnek, örneğin bir keyUp olayına tepki verir ve 300 ms için yeni bir keyUp bulunana kadar bekler ve sonra eventHandler çağırır, ancak sadece yeni değer (300 ms sonra) son yayılan değerden farklıysa.

0

Bu benim yolum, C# 7.0 sözdizimi özelliğini kullan. Bazı zaman aşımı eylemi yürütüldüğünde, js'ye göre farklı olur, o zaman açık olamaz.

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(); 
    } 
}