2010-10-18 40 views
7

मेरे आवेदन में मैं एक आरएसएस फ़ीड में अपडेट की जांच करने के लिए टाइमर का उपयोग कर रहा हूं, यदि नए आइटम मिलते हैं तो मैं उपयोगकर्ता को सूचित करने के लिए एक कस्टम संवाद पॉप अप करता हूं। जब मैं मैन्युअल रूप से चेक चलाता हूं तो सबकुछ बढ़िया काम करता है, लेकिन जब टाइमर में स्वचालित चेक चलाया जाता है तो ईवेंट को प्रदर्शित नहीं किया जाता है।टाइमर थ्रेड से जीयूआई थ्रेड पर कॉल विधि

सबसे पहले यह एक धागा मुद्दा है? (मुझे लगता है कि ऐसा इसलिए है क्योंकि मैन्युअल और स्वचालित जांच दोनों एक ही कोड का उपयोग करते हैं)।

जब मैं स्वचालित जांच चलाता हूं, तो क्या मुझे उस विधि को आमंत्रित करना होगा जो टाइमर समाप्त हुए ईवेंट हैंडलर से चेक चलाता है?

क्या मेरे कस्टम संवाद वर्ग में मुझे कुछ करने की ज़रूरत है?

संपादित करें: यह एक विनफॉर्म एप्लिकेशन है।

यहां कोड का उदाहरण है इसका एक उदाहरण है। (कृपया इस कोड उदाहरण में वाक्यविन्यास त्रुटियों को इंगित न करें, यह एक साधारण उदाहरण है वास्तविक कोड नहीं)।

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

टिप्पणियों और कुछ उत्तर पढ़ने के बाद, मुझे लगता है कि मेरी समस्या यह है कि मैं एक System.Timers.Timer नहीं एक System.Windows.Forms.Timer का उपयोग कर रहा है।

संपादित करें:

एक Forms.Timer प्रारंभिक परीक्षण करने के लिए बदलने के बाद अच्छा लग रहा है (लेकिन कोई नए आइटम अभी तक तो मौजूद कस्टम संवाद नहीं देखा है)। अद्यतन विधि कहलाते समय मैंने फ़ाइल में थ्रेड आईडी आउटपुट करने के लिए थोड़ा सा कोड जोड़ा। टाइमर का उपयोग करना। थ्रेड आईडी को जीआईआई थ्रेड नहीं था, लेकिन फॉर्म का उपयोग करना। थ्रेड आईडी को जीआईआई के समान ही है।

+3

हाँ, यह एक थ्रेडिंग समस्या है - लेकिन उत्तर इस बात पर निर्भर करता है कि आप WPF या WinForms का उपयोग कर रहे हैं या नहीं? – x0n

+0

और मुझे आश्चर्य है कि आप कोई अपवाद नहीं देख रहे हैं: .NET का कौन सा संस्करण आप इसे चला रहे हैं? क्या आप कुछ नमूना कोड दिखा सकते हैं? –

+0

क्या आप कोड पोस्ट कर सकते हैं? – TalentTuner

उत्तर

15

Which timer क्या आप उपयोग कर रहे हैं? System.Windows.Forms.Timer स्वचालित रूप से UI थ्रेड पर ईवेंट को सक्रिय करता है। यदि आप अन्य का उपयोग कर रहे हैं तो आपको यूआई थ्रेड पर विधि कॉल करने के लिए Control.Invoke का उपयोग करना होगा।

+0

System.Windows.Forms.Timer में बदलना समस्या हल हो गई। धन्यवाद। – Tester101

+0

+1000! System.Windows.Forms.Timer मेरे सभी निराशाजनक "ऑब्जेक्ट को किसी अन्य धागे पर बनाया गया" टाइमर मुद्दों को हल करता है! धन्यवाद! –

+0

एक मजाक की तरह, मैंने इसके लिए एक दिन बिताया! धन्यवाद और जागरूक रहें – aozan88

0

क्या आपका आवेदन एक WPF-अनुप्रयोग है? यदि ऐसा है, तो आपको यूआई थ्रेड से जुड़े डिस्पैचर में अपने पृष्ठभूमि-थ्रेड से काम का प्रतिनिधि होना चाहिए।

पोस्ट कुछ कोड, तो आप बेहतर मदद मिल और डिस्पैचर वर्ग पर एक नज़र हो सकता है तो http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke.aspx

1

आप Forms.Timer यहाँ का उपयोग करना चाहिए, या यदि आप टाइमर के अन्य प्रकार का उपयोग करें, .Invoke() साथ UI के लिए कॉल को क्रमानुसार

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); 
    } 
संबंधित मुद्दे