2011-11-06 15 views
8

Daha iyi bir tasarıma sahip Task görevinden daha iyi bir tasarıma ihtiyacım var Thread.Sleep, Görev sınıfını kullanıyorum.X zaman süresi ve rapor ilerlemesi için bekleyiniz.

Benim wpf uygulamasında bir Görev yürüttüğümde, bu görevin her biri bir kaç görev çalıştırıyor, bu görevlerin her biri önce giriş yapıyorlar ve İnternet web sitesi, giriş yaptıktan sonra birkaç saniye beklemeli ve devam edecekleri zaman kullanıcıyı bilgilendirmelidirler daha fazla ve bu benim sorunum, çünkü Thread.Sleep ile ilerlemeyi bildiremiyorum.

Oturum açmadan daha fazla işlev var, yaklaşık 5-6, hepsi bir Internet kaynağı istiyor ve aralarında geriye kalan zaman raporunun gönderilmesiyle birlikte bir uyku zamanı olması gerekiyor gui, bu 5-6 işlevi Bir Görevde, ancak birçok görev olabilir. i gerekenler

görev beklemesi, aynı zamanda GUI geçmek için kalan zamanında güncellemeleri göndermek için izin vermektir.

Bu sorunla ilgili herhangi bir fikriniz var mı, nasıl daha iyi hale getirilir, belki de böyle bir sorun için tasarım desenleriniz var mı?

Ayrıca Thread.Sleep'ın zayıf bir tasarım uygulaması olduğunu duydum.

DÜZENLEME: kimse bilmiyor? İplik ile beklemede bir tür süreölçerle bekleyiniz waithandle, autoresetevent, anybody?

+1

süre geri bu soruya iyi bir cevap var: http://stackoverflow.com/questions/7311468/best-practice-for-thread-delays-with-countdown-notification – drharris

+0

Thx, çok yararlı . – Programista

cevap

1

Thread.Sleep'ı kullanmayı unut. Bunun yerine, görevinizi bir arka plan iş parçacığında çalıştırın ve bir AutoResetEvent ile bir WaitHandle kullanın. (Bağlantılar: WaitHandle/WaitOne/AutoReset)

güncellemelerini gönderebilir Geçmişiniz iplik zaman uyumsuz delegelerle UI, ama her iki şey olur dek çağıran iş parçacığı bunu bekler: o kadar görevini tamamlamış

1) Kişisel iplik raporlarını yourwaithandle.Set() kullanarak

veya ) bekleme iplik zaman aşımı (zaman aşımı değerini WaitOne parametre olarak ayarlanır() kullanılan yöntem).

+0

Evet, aynı şeyi baştan beri düşünüyordum ama kimse bu yöne işaret etmiyordu, neden ben de bilmiyorum, ayrıca drharris bağlantı formunu da çok yararlı buluyorum. biraz lo yapacak waithandle veya sıfırlama olay ve zamanlayıcı dayalı, kendi başıma gic. – Programista

1

yerine tek bir görev, bu yarım düzineden fonksiyonları (giriş, vs.) her yerine sahip olmak yerine, her biri ayrı bir görevi işlev yapmak. Daha sonra zamana göre sıralanan bir öncelik sırası oluşturabilirsiniz. Bu meta görevlerden birini başlatmak istediğinizde, ilk işlevini, sıradaki verileri (ör. URL, kullanıcı kimliği, parola vb.) Ile birlikte bir sıraya yerleştirirsiniz.

Her işlev tamamlandığında, gerçekleştirilecek bir sonraki işlevi sıraya alır. İlk iki işlev giriş ve get_data eğer Yani, olurdu:

queue login with state data to execute at DateTime.Now 
When login is finished, it queues get_data with the state data and DateTime.Now + 5 seconds (or whatever time) 

son işlevi yerine getirdiğinde, bu yerde sonuçlarını nakleder.

Daha sonra kuyruğunu saniyede 10 kere anket (ya da bir şey kuyruğuna eklenir her Zamanlayıcı sonraki kene zaman güncellenecektir var) bir zamanlayıcı ayarlayabilirsiniz. Bireysel görevleri gerektiği gibi başlatabilir.

Yeni Async CTP, şu anda bu tür bir şeye sahip olabilir: "zamanında görev yürüt". Bakmaya değer olabilir. başlatıldığında ilerleme rapor gelince

, her fonksiyonu (yani "in günlüğü" "verileri almak için 5 saniye bekledikten ..." ... vb "veri alma") ilerlemeyi bildirebilirsiniz İsterseniz, sizi Zamanlayıcı iş parçacığını öncelik sırasına düzenli olarak yürütebilir ve belirli görevler yürütüldüğünde rapor verebilir. Bu aşırı olmasına rağmen olabilir.

Ve ne duymuş haklı: Thread.Sleep parçacığı havuzu iş parçacığı birlikte çalışıyoruz, özellikle son derece kötü bir fikir.

+0

Bu iyi bir çözüm değildir, çok iş parçacıklı bir uygulamada bile yapısal bir kod gerekir, her bir görevde 5-6 işlevi iyidir, hepsi birbiriyle bağlantılıdır, her görevi ayrı bir görevde yapmak karışıklık olur, her görev kod oldukça, ben queuing fonksiyonu gerçek bir çözüm olduğunu sanmıyorum, daha iyi bir şey arıyorum, bu işlevler tek bir görevde birlikte olduğu yanlış bir şey yok, bu kod iyi ama uyku kısmı değil. Daha iyi bir yol olmadığını düşünmeyi reddediyorum. "5 saniye beklemek" olamaz, gerçek bir geri sayım olmalı ve izleme periyodu biraz "kesmek" tir. – Programista

+0

@Programista: Konu, bir iş parçacığını geciktirmenin tek yolunun uyumasıdır. Ve uyku kötü olduğu için, bir şeyleri kırmak için başka bir yolla gelmelisin. –

+0

Bu doğru değil, görev başka bir işlev tarafından durdurulabilir, ancak özellikle de kalan zaman güncellemesinin nasıl yapıldığını anlatmak için bunu yapmış birisine ihtiyacım var. – Programista

6

Çözüm, eşzamanlı bir beklemeden ziyade async geri çağırma olarak ele almaktır. Bu aynı zamanda veri akışı veya Rx için ideal bir kullanım vaka gibi görünüyor

async item => { await Task.Delay(1000); Process(item); }

: Eğer zaman uyumsuz CTP üzerinde ise hiç , doğru yol olacaktır.

kullanma Reaktif Uzantıları:

static void Track(int timeout, int frequency, string item) 
    { 
     Observable.Interval(TimeSpan.FromSeconds(frequency)) //produces 0, 1, 2.. with the interval 
        .Do(i => Console.WriteLine("Working on {0}", item)) // work on item 
        .TakeUntil(Observable.Timer(TimeSpan.FromSeconds(timeout))) //stop once the timer publishes a value 
        .Subscribe 
        (
         i => Console.WriteLine("Reporting {0}%", ((double)(i + 1)/timeout * 100)), // the interval reaches OnNext 
         e => Console.WriteLine("Error!"), // error occured 
         () => Console.WriteLine("Completed") // observable completed 
       ); 
    } 

Track(timeout: 5, frequency: 1, item: "http://example.com/?") ile bu çağırarak günü, üretilen çıktı şöyle olur:

Working on http://example.com/? 
Reporting 20% 
Working on http://example.com/? 
Reporting 40% 
Working on http://example.com/? 
Reporting 60% 
Working on http://example.com/? 
Reporting 80% 
Completed 
+0

İlginç, üretim hazır ticari bir uygulama olduğu için Async CTP'yi kullanamıyorum, ancak bu seçeneği bazı yardımcı sınıflarla normal şekilde kontrol edeceğim. Dahili zamanlayıcı sayımına sahip, kendiliğinden bir engelleme senaryosunda bazı otomatik veya manuel sıfırlama olayı hakkında ne düşünüyorsunuz? – Programista

+0

@Programista Engelleme çözüm değildir. Bu durumda gerçekten ihtiyacınız olan şey bir geri çağırmadır. Devam eden geçiş stili kullanmak gibi. İlgilendiğinizde Microsoft'un Reaktif Uzantıları'nı (Rx) kullanarak bir çözüm eklemek için cevabı düzenleyeceğim. – Asti

+0

Rx'i tanımıyorum, bu bana yardım eder. – Programista

0

sen ara sayfayı gerçekleştirmek için (System.Timers itibaren) bir Timer kullanarak düşündünüz mü " "mesaj güncellemeleri mi kaldı? Görevlerinizin her biri tamamlanma değeri için beklenen bir süreyi ayarlayabilir, ardından zamanlayıcı göreviniz kullanıcı arayüzünü gerektiği gibi saymak ve güncellemek için sorumlu olabilir. Hiçbir Thread.Sleep gerekli ve Timer bir iş parçacığı havuzu iş parçacığı üzerinde Tick kodunu yürütecek.

+0

Evet, ancak bir senaryoda bir şeyin bir iş parçacığı tarafından engellendiğini ve kene sayımı olarak bir zamanlayıcıyı kullandığını ve sonra da keneleri sayar (kene 100ms, 1 saniye vb.).yaklaşıma göre) ve zamanla sıfır her saniye ui için güncelleme göndermek, zaman sıfıra giderse, iplik serbest bırakılır ve kendi içinde bulunan blok iplik, sayma ve güncelleme ui atılır. – Programista

+0

Tek tek görevlerin ilerlemesini izleyen genel bir toplam zamanlayıcıdan bahsediyorum. Bence bireysel görevlerde çok fazla uğraşmaya çalışıyorsun; eğer bir görevin sonu da UI'yi kullanırsa, bu benim için kırmızı bir bayrak çıkarır. –

+0

Hayır, hayır, bir monitör olarak çalışamaz, örneğin 3 saniyeliğine görev engellenir, ancak "bekle 3..2.1" ibaresini görüntülemem gerekir. Belki bir zamanlayıcı, diğer nesneler için geri sayım amaçları için küresel bir 100 ms zaman referansı olarak kullanılabilir ve ui atılmaz, ben ipliğini bloke eden, kalan zamanı ve güncellenmiş kullanıcı arabirimini imha eden mantıksal olarak tek tek nesne/sınıf anlamına gelir zaman 0'a geldiğinde ve iplik bırakıldığında. – Programista

İlgili konular