2010-10-18 15 views
7

Uygulamamda, bir RSS beslemesinde güncelleştirmeleri denetlemek için bir zamanlayıcı kullanıyorum, yeni öğeler bulunursa, kullanıcıyı bilgilendirmek için özel bir iletişim kutusu açarım. Kontrolü el ile çalıştırdığımda her şey harika çalışıyor, ancak otomatik kontrol zamanlayıcılar Elapsed olayında çalıştığında, özel iletişim kutusu görüntülenmiyor.GUI iş parçacığı üzerinde bir zamanlama iş parçacığı çağrısı yöntemi çağrısı

Öncelikle bu bir iş parçacığı mıdır? (Bunun nedeni hem manuel hem otomatik kontrolün aynı kodu kullanmasıdır).

Otomatik denetimi çalıştırdığımda, Zamanlayıcı Elapsed olay işleyicisinden denetimi çalıştıran yöntemi çağırmam gerekir mi?

Özel iletişim sınıfımda yapmam gereken bir şey var mı?

Düzeltme: Bu bir winforms uygulamasıdır.

İşte kodun nasıl bir örneğidir. (Lütfen bu kod örneğinde sözdizimi hatalarını işaret etmeyin, bu sadece gerçek bir örnek değil gerçek bir koddur).

public class MainForm : System.Windows.Forms.Form 
{ 
    //This is the object that does most of the work. 
    ObjectThatDoesWork MyObjectThatDoesWork = new ObjectThatDoesWork(); 
    MyObjectThatDoesWork.NewItemsFound += new NewItemsFoundEventHandler(Found_New_Items); 

    private void Found_New_Items(object sender, System.EventArgs e) 
    { 
     //Display custom dialog to alert user. 
    } 

    //Method that doesn't really exist in my class, 
    // but shows that the main form can call Update for a manual check. 
    private void Button_Click(object sender, System.EventArgs e) 
    { 
     MyObjectThatDoesWork.Update(); 
    } 

    //The rest of MainForm with boring main form stuff 
} 


public class ObjectThatDoesWork 
{ 
    System.Timers.Timer timer; 

    public ObjectThatDoesWork() 
    { 
     timer = new System.Timers.Timer(); 
     timer.Interval = 600000; 
     timer.AutoReset = true; 
     timer.Elapsed += new new System.Timers.ElapsedEventHandler(TimeToWork); 
     timer.Start(); 
    } 

    private void TimeToWork(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     Update(); 
    } 

    public void Update() 
    { 
     //Check for updates and raise an event if new items are found. 
     //The event is consumed by the main form. 
     OnNewItemsFound(this); 
    } 

    public delgate void NewItemsFoundEventHandler(object sender, System.EventArgs e); 
    public event NewItemsFoundEventHandler NewItemsFound; 
    protected void OnNewItemsFound(object sender) 
    { 
     if(NewItemsFound != null) 
     { 
      NewItemsFound(sender, new System.EventArgs()); 
     } 
    } 
} 

görüş ve bazı yanıtlar okuduktan sonra benim sorunum ben System.Timers.Timer değil System.Windows.Forms.Timer kullanıyorum olduğunu düşünüyorum.

DÜZENLEME:

bir Forms.Timer ilk testlere değiştirdikten sonra iyi görünüyor (ancak yeni öğeler özel iletişim görmedim bu yüzden henüz var). Güncelleme yöntemi çağrıldığında iş parçacığı kimliğini bir dosyaya vermek için biraz kod ekledim. Timers.Timer kullanarak iş parçacığı kimliği GUI iş parçacığı değildi, ancak Forms.Timer kullanarak iş parçacığı kimliği GUI ile aynıdır.

+3

Evet, bu bir iş parçacığı sorunudur - ancak yanıt WPF veya WinForms kullanıp kullanmadığınıza göre değişir: hangisi? – x0n

+0

Ve herhangi bir istisna görmediğinize şaşırdım: .NET'in hangi sürümü üzerinde çalışıyorsunuz? Örnek kod gösterebilir misin? –

+0

Kodu gönderir misiniz? – TalentTuner

cevap

15

Which timer kullanıyor musunuz? System.Windows.Forms.Timer otomatik olarak UI iş parçacığı olayını tetikler. Başka birini kullanıyorsanız, UI iş parçacığı üzerinde yöntemi çağırmak için Control.Invoke kullanmanız gerekir.

+0

System.Windows.Forms.Timer ile değiştirmek sorunu çözdü. Teşekkür ederim. – Tester101

+0

+1000! System.Windows.Forms.Timer tüm çok sinir bozucu "Nesne üzerinde oluşturulan başka bir konu" zamanlayıcı sorunları çözer! Teşekkürler! Bir şaka gibi –

+0

, bunun için bir gün geçirdim! Teşekkürler ve farkında olun – aozan88

1

Sen zamanlayıcılar başka türlü kullanırsanız veya .Invoke() ile UI aramaları seri burada Forms.Timer kullanmalıdır

0
private static System.Threading.SynchronizationContext _UI_Context; 
    //call this function once from the UI thread 
    internal static void init_CallOnUIThread() 
    { 
     _UI_Context = System.Threading.SynchronizationContext.Current; 
    } 
    public static void CallOnUIThread(Action action, bool asynchronous = false) 
    { 
     if (!asynchronous) 
      _UI_Context.Send((o) => 
      { 
       action(); 
      }, null); 
     else 
      _UI_Context.Post((o) => 
      { 
       action(); 
      }, null); 
    } 
İlgili konular