2016-03-23 29 views
0

Bu yüzden ana kullanıcı arayüzünde bir duraklatma düğmesine sahip bir programımız var. Duraklat düğmesine basıldığında bir zaman damgası kaydedilir ve tekrar basıldığında başka bir zaman damgası oluşturulur, bu ikisi arasındaki zaman farkı hesaplanır ve daha sonra bir kullanıcı adı ile birlikte tüm 3 değerleri WebClient kullanılarak bir db'ye gönderilir. Sorun şu ki, düğmeye birden çok kez hızlı basılırsa, gönderilen tüm verilerin alınmasıyla ilgili sorunlar vardır.Bir Backround çalışanı kullanmalı mıyım veya kendi thread'ımı yazmalıyım

Bir kuyruğa girme fikri vardı ve veriyi göndererek duraklama düğmesi yerine bir sıraya yazdıracak ve daha sonra ayrı bir iş parçacığına sahip olacaksınız ve kuyruğu da göndericiye yönlendirecek.

Arka plan işçisini, her kuyruğa basmak için her x-saniyede bir kuyruğu okuyup sıradan bir aşırı okuma/kötüye kullanma hissi veriyorsa, veri göndermek için kullanma. Haklıyım ve bu normal bir iş parçacığı mıdır, yoksa arka plan işçisinin gideceği yol mu?

+0

_ "... bir zamanlayıcı kullanarak overkill/istismar gibi hissediyor". "kendi konularımı yaz" tartışmalı bir şekilde aşırı. WinForms için, bir "BackgroundWorker", .NET 2+ 'de mevcut olduğu için en iyi bahistir. Aksi halde, 'Görev' – MickyD

cevap

2

Bir BlockingCollection sınıfta sarılmış bir ConcurrentQueue kullanın ve toplama izlemek için Görev kullanırsınız.

var pendingEntries = new BlockingCollection<List<Entry>>(new ConcurrentQueue<List<Entry>>()); 
var loggingTask = System.Threading.Tasks.Task.Factory.StartNew(ConsumerTask, pendingEntries); 

Sınıf Girişi, bir kerede kaydetmek istediğiniz her şey için bir kapsayıcıdır.

tüketici görev şuna benzer:

pendingEntries.CompleteAdding(); 
: Eğer girdileri ekledikten sonra

var newEntry = new Entry(......); 
pendingEntries.Add(newEntry); 

, bu çağrı:

private void ConsumerTask(object parameter) 
{ 
    var localPendingEntries = (BlockingCollection<List<Entry>>)parameter; 
    foreach (var entry in localPendingEntries.GetConsumingEnumerable()) 
    { 
     // push the 'entry' where you want. 
    } 
} 

bunu kuyruğa girdiler eklemek için

Görev, finişe sahip olduğunda foreach döngüsünden düşecek d sıradaki girişleri işlemek. Daha sonra birlikte tamamlamak için görev için bekleyebilir

: _

loggingTask.Wait(); 
pendingEntries.Dispose(); 
+0

Duraklama olayı için veriyi bir sınıfta saklıyorum Çağrı PauseEvent, Giriş Girin PauseEvent sınıfım mı yoksa kullanmam gereken bir giriş sınıfı mı var? – user5999614

+0

Duraklat düğmesine ikinci kez tıklattığınızda sıraya olay eklemek istiyorum. Düğmenin her bir tıklatılışında yalnızca bir olay ekliyorum, bu yüzden PauseButton_Click() yönteminde 'pendingEntries.Add()' ve 'pendingEntries.CompleteAdding()' i çağırırım mı? Tüketici yöntemi sadece MainForm sınıfına giriyor mu? PendingEntries ve loggingtask tanımları nereye gider? – user5999614

+0

Örnek kodumda, Giriş istediğiniz herhangi bir şey olabilir. PauseEvent sınıfınızın oraya gidebileceği gibi geliyor. –

0

Kişisel olarak iş parçacığı kullanıyorum. Backgroundworkers benim için çok fazla kod aldı. Eğer iş parçacığı global değişken olarak varsa, iş parçacığı irade ile öldürebilir veya başlatabilirsiniz.

burada bir göz atın: BackgroundWorker vs background Thread

hem iş parçacığı için ve onlar çalıştırıyorsanız görebiliyorsanız backgroundworker. Çalışıyorlarsa, çalıştırıyorsa düğmeyi devre dışı bırakabilir veya düğmeyi herhangi bir şey yapmadığı için yapabilirsiniz. Yaptığın şey için arka plan çalışanını tavsiye ederim.

+0

kullanın. Arka plan işçisini kötüye kullanmadığımdan emin olduğum için stille çok ilgilenmiyorum. arka plan işçisini kullanmasa da, kötüye kullanım sorununu çözüyordu. – user5999614

+0

Kötüye kullandığınıza inanmıyorum. Backgroundworker her şeyi halledebilmelidir. –

+0

Aslında, bir BackgroundWorker da sadece iş parçacığı, bu yüzden 'kötüye' olamaz. Ancak bu, düz bir iş parçacığından biraz daha ağırdır, çünkü kutunun dışında ek özellikler (rapor ilerleme durumu, tamamlanmış etkinlik, ...) vardır. Bu özelliklere ihtiyacınız varsa bir BgWorker kullanın. Onlara ihtiyacınız yoksa düz bir iş parçacığı kullanın. – derpirscher

0
protected void btnPause_Click(object sender, EventArgs e) 
    { 
     System.ComponentModel.BackgroundWorker disableWorker = new System.ComponentModel.BackgroundWorker(); 
     disableWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(disableWorker_DoWork); 
     disableWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(disableWorker_RunWorkerCompleted); 
     disableWorker.RunWorkerAsync(); 
    } 

    void disableWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) 
    { 
     btnPause.Enabled = true; 
    } 

    void disableWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 
     btnPause.Enabled = false; 
     System.Threading.Thread.Sleep(10000);    
    } 
+1

Cevabınızı iyileştirmeyi düşünün. _ [Sadece kod yanıtları 'Çok Düşük Kalite' kapsamında olabilir ve silme için adaylar ... Her zaman bir kod fabrikası olmadığımızı belirttik. Başkalarını balık tutmayı öğreten insanlar biziz. Sadece kod yanıtları sadece bir gün için bir insanı besler] (http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code -only-ques) _ – MickyD

İlgili konular