Results 1 to 17 of 17

Thread: [RESOLVED] Make Timer run operation in the Background

  1. #1

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Resolved [RESOLVED] Make Timer run operation in the Background

    hi guys! is ther anyway for me to make my Timer_Tick eventhandler run operation in the Background becuase the eventhandler perform a lot of task and time consuming that cause my User Interface to seem as though it has stopped responding while they(The code under the Timer_Tick EventHandler) are running. Will guys please help me with this. Thanks in advance!
    Last edited by daimous; Oct 20th, 2006 at 02:04 AM.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    I'd suggest not using a single BackgroundWorker if you need more than one worker thread running at a time. You could write your event handlers ahead of time and then in your Timer's event handler you create a new BackgroundWorker, attach it to the appropriate event handlers and then run it.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    Sorry, i think i explain my problem i lil vague..becuase what i want is, Is to run any code under Timer_Tick eventhandler in Background becuase that is where delays happen which cause my User Interface to seem as though it has stopped responding. Maybe i'll just remove the code above becuase that makes my question vague.

  4. #4

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    There was nothing wrong with your explanation. I'm saying that each time the Timer Ticks you create a BackgroundWorker and send it on its way. If your Timer Ticks again before that backgroundWorker has finished its task there's no issue because you won't be trying to use it again:
    VB Code:
    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2.     'Create a new worker.
    3.     Dim worker As New System.ComponentModel.BackgroundWorker
    4.  
    5.     'Attach the appropriate event handlers.
    6.     AddHandler worker.DoWork, AddressOf BackgroundWorker_DoWork
    7.     AddHandler worker.RunWorkerCompleted, AddressOf BackgroundWorker_RunWorkerCompleted
    8.  
    9.     'Set the worker to work.
    10.     worker.RunWorkerAsync()
    11. End Sub
    12.  
    13. Private Sub BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
    14.     'Perform long-running operation here.
    15. End Sub
    16.  
    17. Private Sub BackgroundWorker_RunWorkerCompleted(ByVal sender As Object, _
    18.                                                 ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
    19.     'A worker has just completed its work so dispose it.
    20.     DirectCast(sender, System.ComponentModel.BackgroundWorker).Dispose()
    21. End Sub
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    Actually, you may need to keep a reference to the BackgroundWorker as well so that it doesn't get cleaned up by the garbage collector:
    VB Code:
    1. Private workers As New List(Of System.ComponentModel.BackgroundWorker)
    2.  
    3. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    4.     'Create a new worker.
    5.     Dim worker As New System.ComponentModel.BackgroundWorker
    6.  
    7.     'Attach the appropriate event handlers.
    8.     AddHandler worker.DoWork, AddressOf BackgroundWorker_DoWork
    9.     AddHandler worker.RunWorkerCompleted, AddressOf BackgroundWorker_RunWorkerCompleted
    10.  
    11.     'Add the worker to the list of active workers so it is not released to the garbage collector.
    12.     Me.workers.Add(worker)
    13.  
    14.     'Set the worker to work.
    15.     worker.RunWorkerAsync()
    16. End Sub
    17.  
    18. Private Sub BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
    19.     'Perform long-running operation here.
    20. End Sub
    21.  
    22. Private Sub BackgroundWorker_RunWorkerCompleted(ByVal sender As Object, _
    23.                                                 ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
    24.     Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    25.  
    26.     'A worker has just finished its work so destroy it and release it to the garbage collector.
    27.     Me.workers.Remove(worker)
    28.     worker.Dispose()
    29. End Sub
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    Thanks dude! But the thing that Im trying to implement is a little different from the code you give me. actually, what im trying to do is to perform long-running operation each time Timer Ticks so the long-running operation should be under Timer1_Tick Eventhandler and Timer_Tick is the one i will call from the BackgroundWorker_DoWork. In other words I will place the long-running operation under Timer1_Tick and Timer1_Tick under BackgroundWorker_DoWork but im not sure is this is posible and if it is the right way.

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    That makes no sense I'm afraid. You don't call the Timer's Tick event handler. It is invoked automatically when the Timer raises its Tick event. The Timer Ticks when it Ticks. Each time it Ticks you want to perform a long-running operation, correct? If so then you create a BackgroundWorker on each Tick and it goes off and performs the long-running operation. Anything else is simply not logical.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    Thanks! that make things more clear to me..thanks again..i'll just try to use the code you give me.

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    Note also that it's only worth using the BackgroundWorker if you need to use either its ProgressChanged and/or RunWorkerComplete events. If there's nothing specific that you need to do in the main thread when each worker has finished then you may as well take popskie's advice and just create a Thread object explicitly as it is easier. The BackgroundWorker is advantageous when you need to communicate with the main thread from the worker thread or if you want to use the same component multiple times to run a background task. If you're not doing either of those things then using the BackgroundWorker isn't worth the effort.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    I have tried to use the Thread but its just the same my form stop each time the timer_ ticks...but i dunno if i implement it right will you please check it. Thanks!
    Code:
            private void Alarm_timer_Tick(object sender, EventArgs e)
            {
                Thread thread_GetEvents = new Thread(new ThreadStart(GetEvents));
                thread_GetEvents.Start();
                thread_GetEvents.Join();
            }
    
            private void GetEvents()
            {
                List_Service.Lists listService = new List_Service.Lists();
                listService.Credentials = new NetworkCredential("username", "password", "domain");
                listService.PreAuthenticate = true;
    
                XmlDocument xmlDoc = new System.Xml.XmlDocument();
    
                XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
                XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
                XmlNode ndQueryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
    
                ndQueryOptions.InnerXml = "<IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>" +
                    "<DateInUtc>FALSE</DateInUtc>";
                ndQuery.InnerXml = "<Where><And><IsNotNull><fieldRef Name='Alarm'/></IsNotNull>" +
                                   "<IsNotNull><fieldRef Name='Alarm_x0020_For'/></IsNotNull>" +
                                   "</And></Where>";
                try
                {
                    XmlNode ndListItems = listService.GetListItems("Events", null, ndQuery, null, null, ndQueryOptions);
                    GetItems(ndListItems);
                }
                catch (System.Web.Services.Protocols.SoapException ex)
                {
                    MessageBox.Show("Message:\n" + ex.Message + "\nDetail:\n" + ex.Detail.InnerText +
                         "\nStackTrace:\n" + ex.StackTrace + "\n\nPlease contact your administrators.", "BCMD");
                    Alarm_timer.Stop();
                }
                
            }
    
            private void GetItems(XmlNode xmlFragment)
            {
                XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlFragment.OwnerDocument.NameTable);
                nsManager.AddNamespace("s", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");
                nsManager.AddNamespace("dt", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");
                nsManager.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
                nsManager.AddNamespace("z", "#RowsetSchema");
                nsManager.AddNamespace("", "http://schemas.microsoft.com/sharepoint/soap/");
    
                XmlNodeList rowNodes = xmlFragment.SelectNodes("rs:data/z:row", nsManager);
                foreach (XmlNode rowNode in rowNodes)
                {
                    DateTime EvntDate = new DateTime();
                    DateTime AlarmDate = new DateTime();
                    DateTime DateNow = new DateTime();
                    string Alarm_Id;
                    string EvntTitle;
                    string EvntLocation;
                    string AlarmFor;
                    AlarmFor = rowNode.Attributes.GetNamedItem("ows_Alarm_x0020_For").InnerText.ToUpper();
                    EvntDate = DateTime.Parse(rowNode.Attributes.GetNamedItem("ows_EventDate").InnerText);
                    AlarmDate = DateTime.Parse(rowNode.Attributes.GetNamedItem("ows_Alarm").InnerText);
                    DateNow = DateTime.Now;
                    
    AlarmDate).ToString());
                    
                    if (AlarmDate.ToShortDateString() == DateNow.ToShortDateString())
                    {
                        if (AlarmDate.ToShortTimeString() == DateNow.ToShortTimeString())
                        {
                            Alarm_Id = rowNode.Attributes.GetNamedItem("ows_ID").InnerText.ToString();
                            if (lstAlarmDump.FindStringExact(Alarm_Id) == ListBox.NoMatches)
                            {
                                lstAlarmDump.Items.Add(Alarm_Id);
                                //MessageBox.Show("ID : " + Alarm_Id + " EVENT:" + rowNode.Attributes.GetNamedItem("ows_LinkTitle").InnerText.ToString());
                                EvntTitle = rowNode.Attributes.GetNamedItem("ows_LinkTitle").InnerText.ToString();
                                EvntLocation = rowNode.Attributes.GetNamedItem("ows_Location").InnerText.ToString();
                                
                                show_Alarm_notification(EvntTitle,EvntDate.ToString(),EvntLocation);
                                //MessageBox.Show("ALARM FOR" + AlarmFor);
                            }
                        }
                    }
                    
                }
            }
    
            public void show_Alarm_notification(string ArgEvntTitle, string ArgEvntDate, string ArgEvntLocation)
            {
                int notification_y_coor;
                Rectangle workingArea = Screen.PrimaryScreen.WorkingArea;
     
                Alarm_data EvntData = new Alarm_data();
                EvntData.EvntTitle = ArgEvntTitle;
                EvntData.EvntDate = ArgEvntDate;
                EvntData.EvntLocation = ArgEvntLocation;
                SoundPlayer sndAlarm = new SoundPlayer();
                Notification Notification_frm = new Notification();
                Notification_frm.ParentData = EvntData;
                Notification_frm.TopMost = true;
                Notification_frm.StartPosition = FormStartPosition.Manual;
                notification_y_coor = workingArea.Height;
                //workingArea.Height - Notification_frm.Height;
                //MessageBox.Show("TITLE: " + EvntTitle + " Date: " + EvntDate + " Location: " + EvntLocation);
                Notification_frm.Show();
                for (int x = 0; x <= Notification_frm.Height; x++)
                {
                    Notification_frm.Location = new Point(workingArea.Width - Notification_frm.Width, workingArea.Height - x);
                }
    
                if (File.Exists(txtSettingSoundFile.Text))
                {
                    sndAlarm.SoundLocation = txtSettingSoundFile.Text;
                }
                else
                {
                    sndAlarm.Stream = Properties.Resources.WARNING;
                }
                sndAlarm.Play();
    
            }

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    Of course your form freezes. You're calling Join on the new Thread. Have you read what Join does? It blocks the current thread until the thread jou're joining completes.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  13. #13

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    opppppsss!!! sorry i forgot to remove the join..but im just wondering why my notification form that i show in "show_Alarm_notification" notification method is automatically closed or it disappear and if that will be the case my alarm notification will be useless...whats wrong?

  14. #14
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    I posted previously that it is only worth using a BackgroundWorker if you need to use its ProgressChanged or RunWorkerComplete events. Basically that means if you want to notify the UI thread of something during execution of the worker thread (ProgressChanged) or when execution of the worker thread completes (RunWorkerComplete). If you're trying to use a MessageBox then it sounds a lot like your trying to notify the UI of something, so the BackgroundWorker is appropriate.

    If you display a MessageBox directly from a worker thread then it is NOT displayed as a modal dialogue of the main form. That's because the two forms' handles are owned by different threads. A MessageBox displayed from a worker thread will NOT prevent the user accessing any form not also created on that same worker thread. To make it prevent access to your main form you would need to use delegate to invoke a method on the UI thread. THAT is why you would use a BackgroundWorker. It's ProgressChanged and RunWorkerComplete events are raised in the UI thread so explicit delegation is not required. That's the whole reason for the BackgroundWorker's existence.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  15. #15

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    ohhh...so i really need to use BackgroundWorker..but im heaving a little with this line of code you posted above becuase when i try to convert it to C#, using the converter from your signature, it has an error. is there something wrong the code below? is "Of" really needed?
    Code:
    Private workers As New List(Of System.ComponentModel.BackgroundWorker)

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Make Timer run operation in the Background

    Ah, sorry. I forget that I'm in the C# forum sometimes when I get here via my UserCP. You should have said something. The way to create a generic List in C# is:
    Code:
    private List<System.ComponentModel.BackgroundWorker> workers = new List<System.ComponentModel.BackgroundWorker>();
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  17. #17

    Thread Starter
    Fanatic Member daimous's Avatar
    Join Date
    Aug 2005
    Posts
    657

    Re: Make Timer run operation in the Background

    its ok...Maybe next time i will.. Thanks for all the help anyway.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width