Results 1 to 11 of 11

Thread: [RESOLVED] Send bulk SMS progressbar and backgroundworker

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Resolved [RESOLVED] Send bulk SMS progressbar and backgroundworker

    Okay. I have an issue an i need help. I am sending a message to a list of numbers stored in a text file. What i do is to loop through all the numbers and send an sms to one after the other using the method used to send to a single number.

    Issue is: i want to display progress in a maquee progressbar untill when i finish sending. I guess this works hand in hand with a backgroundworker. I have tried this but i get an error "Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on." on the line with "objSmsMessage.Data = tbMessage.Text;"

    below is my code. I need help. Iam so daft when it comes to progressbars and the backgroundworker.

    SENDING MESSAGE
    Code:
       private void btnStart_Click(object sender, EventArgs e)
            {
                lblConnectionStatus.Text = "";
                btnCancel.Enabled = true;
                btnStart.Enabled = false;
                ProgressBar1.Value = 0;
                Cursor = Cursors.WaitCursor;
                backgroundWorker1.RunWorkerAsync();
            }
    Code:
        private void SendBulk()
            {
                // Set Cursor
                //Cursor.Current = Cursors.WaitCursor;
    
                for (int i = 0; i < 100; i++)
                {
                    using (StreamReader reader = File.OpenText(tbMessageRecipient.Text))
                    {
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            objSmsMessage.Recipient = line;
    
                            string strMessageReference;
                            object obj;
    
                            objSmsMessage.Clear();
                            objSmsMessage.RequestDeliveryStatus = _frmSmsSendOptions.bDeliveryReport ? -1 : 0;
    
                            //Add Many Reciepients and message is sent line by line.
                            objSmsMessage.Recipient = line;
    
                            objSmsMessage.Data = tbMessage.Text;
                            objSmsMessage.Format = objConstants.asMESSAGEFORMAT_TEXT;
                            if (chkUnicode.Checked)
                            {
                                objSmsMessage.Format = objConstants.asMESSAGEFORMAT_UNICODE;
                                if (_frmSmsSendOptions.bImmediateDisplay)
                                    objSmsMessage.Format = objConstants.asMESSAGEFORMAT_UNICODE_FLASH;
                                if (_frmSmsSendOptions.bMultipart)
                                    objSmsMessage.Format = objConstants.asMESSAGEFORMAT_UNICODE_MULTIPART;
                            }
                            else
                            {
                                objSmsMessage.Format = objConstants.asMESSAGEFORMAT_TEXT;
                                if (_frmSmsSendOptions.bImmediateDisplay)
                                    objSmsMessage.Format = objConstants.asMESSAGEFORMAT_TEXT_FLASH;
    
                                if (_frmSmsSendOptions.bMultipart)
                                    objSmsMessage.Format = objConstants.asMESSAGEFORMAT_TEXT_MULTIPART;
                            }
                            if (_frmSmsSendOptions.bUDH)
                                objSmsMessage.Format = objConstants.asMESSAGEFORMAT_DATA_UDH;
    
    
                            obj = objSmsMessage;
                            //SEND MESSAGE
                            strMessageReference = objSmppProtocol.Send(ref obj);
                            UpdateResult(objSmppProtocol.LastError);
                            if (objSmppProtocol.LastError == 0)
                            {
                                //Add sent data to the datagridview.
                                //get the last mID and add 1
                                List<OutBox> messageAdded = new List<OutBox>();
                                messageAdded.Add(new OutBox(1, objSmsMessage.Data, Convert.ToDateTime(DateTime.Now.ToString()), "Delivered", Convert.ToDateTime(DateTime.Now.ToString()), Convert.ToDateTime(DateTime.Now.ToString())));
                                dgvOutbox.DataSource = messageAdded;
                                FormatDgvOutBox();
                            }
    
    
                            // Reset Options in case of a UDH message (i.e.: WAP, Picture, Ringtone)
                            if (_frmSmsSendOptions.bUDH)
                            {	// If this is not done, you cannot send plain text after you've sent WAP, Ringines, Pictures
                                _frmSmsSendOptions.ResetFlags();
                                tbMessage.Text = "";
                            }
                        }
                        // Reset Cursor
                        //Cursor.Current = Cursors.Default;
                    }
                    backgroundWorker1.ReportProgress(i);
                    Thread.Sleep(100);
                }
    
            }
    Code:
          private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                // Get the BackgroundWorker that raised this event.
                //BackgroundWorker worker1 = sender as BackgroundWorker;
                //e.Result = SumNumbers(Convert.ToDouble(e.Argument),worker1,e);
                 SendBulk();
            }
    
       private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                ProgressBar1.Value = e.ProgressPercentage;
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else if (e.Cancelled)
                    MessageBox.Show("Cancelled");
                else
                    lblConnectionStatus.Text = "Complete";
    
                btnStart.Enabled = true;
                btnCancel.Enabled = false;
                Cursor = Cursors.Default;
    
    
                
            }
    
            private void btnCancel_Click(object sender, EventArgs e)
            {
                backgroundWorker1.CancelAsync();
                btnCancel.Enabled = false;
                btnStart.Enabled = true;
            }
    Last edited by maps; Nov 5th, 2009 at 03:25 PM. Reason: Other code

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

    Re: Send bulk SMS progressbar and backgroundworker

    The whole point of the BackgroundWorker is that you do all your background work in the DoWork event handler and you do all of your foreground work, i.e. update the UI, in the ProgressChanged and RunWorkerCompleted events handlers. You're doing lots of updating of the UI in your SendBulk method, which is called from the DoWork event handler, hence the issue.

    You are supposed to call ReportProgress when you want to update the UI. If what you need to do is too complex for that then you will need to use delegation. In that case you can still use a BackgroundWorker if you want. Follow the CodeBank link in my signature and find my submission on accessing controls from worker threads.

    By the way, a Marquee ProgressBar is one that just shows activity without any specific progress value. You're explicitly setting the Value of your ProgressBar so it's not Marquee.
    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
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Re: Send bulk SMS progressbar and backgroundworker

    thanks JMC. at first i had wanted to use a maquee but the only example that i got was that of blocks. Let me look at your submission and i see how it goes.

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

    Re: Send bulk SMS progressbar and backgroundworker

    With the ProgressBar control, if you set the Style property to Marquee then the control will simply show a block of colour moving repeatedly from left to right, much as Windows XP and Vista display as they are starting up. The idea is to indicate that something is happening without specifically indicating how much of it is finished. In that case you don't have to set the Value of the ProgressBar at all. It looks after itself and you change the Style to something other than Marquee when you're done.

    If you are able to calculate how far along an operation is then it's a good idea to do so, so that you can give the user a more accurate idea of how long they have to wait.
    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

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Re: Send bulk SMS progressbar and backgroundworker

    I want to use the maquee style because i cant tell how long the process would take to send messages since the number of reciepients are variable. They would be 200 or 800 or 1500 and so these have different time spans of execution.

    I have read and used the invoke method using a progressbar "block style" but the progress doesnt seem to move at all.

    i used this long executing process below
    Code:
       private void SyncMethod()
            {
                if (tbMessage.InvokeRequired)
                {
                    tbMessage.Invoke(new MethodInvoker(SyncMethod));
                }
                else
                {
                    for (int i = 1; i <= 100; i++)
                    {
                        Thread.Sleep(100);
                    }
                }
            }
    then
    Code:
        private void btnStart_Click(object sender, EventArgs e)
            {
                lblConnectionStatus.Text = "";
                btnCancel.Enabled = true;
                btnStart.Enabled = false;
                ProgressBar1.Value = 0;
                Cursor = Cursors.WaitCursor;
                backgroundWorker1.RunWorkerAsync();
            }
        
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                SyncMethod();
            }
    
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                ProgressBar1.Value = e.ProgressPercentage;
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else if (e.Cancelled)
                    MessageBox.Show("Cancelled");
                else
                    lblConnectionStatus.Text = "Complete";
    
                btnStart.Enabled = true;
                btnCancel.Enabled = false;
                Cursor = Cursors.Default;
    
    
                
            }
    
            private void btnCancel_Click(object sender, EventArgs e)
            {
                backgroundWorker1.CancelAsync();
                btnCancel.Enabled = false;
                //btnStart.Enabled = true;
            }
    I realise that i dont need blocks style, so how can i do this!

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Re: Send bulk SMS progressbar and backgroundworker

    ok. whne i use this, the progressbar only shows and runs to full when the iteration is complete!
    Code:
       private void SyncMethod()
            {
                if (tbMessage.InvokeRequired)
                {
                    tbMessage.Invoke(new MethodInvoker(SyncMethod));
                }
                else
                {
                    for (int i = 1; i < 100; i++)
                    {
                        backgroundWorker1.ReportProgress(i);
                        Thread.Sleep(50);
                    }
                }
            }

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

    Re: Send bulk SMS progressbar and backgroundworker

    You're not reading what I'm posting. If you want a Marquee ProgressBar then you do NOT set the Value property of the ProgressBar at all. You set the Style property to Marquee before you start and then back again when you finish. That is ALL you do for progress.
    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

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Re: Send bulk SMS progressbar and backgroundworker

    Thanks. I have something that works but my CancelAsync method doesnt work.
    What i did is to set the progressbar to marquee using the desiigner, then i would show when the task is taking place then hide it after completion.
    below is what i have.

    How can i have it cancel when cancel button is pressed and is what i have done the right way.

    Code:
       private void MyMethod()
            {
                for (int i = 1; i < 100; i++)
                {
                    Thread.Sleep(100);
                }
            }
    
       private void btnStart_Click(object sender, EventArgs e)
            {
                lblConnectionStatus.Text = "Sending...";
                btnCancel.Enabled = true;
                btnStart.Enabled = false;
                ProgressBar1.Visible = true;
                Cursor = Cursors.WaitCursor;
                backgroundWorker1.RunWorkerAsync();
            }
        
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                MyMethod();
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                    MessageBox.Show(e.Error.Message);
                else if (e.Cancelled)
                    MessageBox.Show("Cancelled");
                else
                {
                    ProgressBar1.Visible = false;
                    lblConnectionStatus.Text = "Complete";
                }
                btnStart.Enabled = true;
                btnCancel.Enabled = false;
                Cursor = Cursors.Default;
    
    
                
            }
    
            private void btnCancel_Click(object sender, EventArgs e)
            {
                backgroundWorker1.CancelAsync();
                btnCancel.Enabled = false;
            }

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

    Re: Send bulk SMS progressbar and backgroundworker

    Again, the information you need has already been provided. That CodeBank submission of mine provides a code example showing how to cancel the background task.
    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

  10. #10

    Thread Starter
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Re: Send bulk SMS progressbar and backgroundworker

    I am sorry, i don't see it! tried the invoke method but it just freezes the progressbar and also when i press the cancel button, i dont get the "Cancelled" messagebox.
    Code:
       private void SyncMethod()
            {
                if (btnCancel.InvokeRequired)
                {
                    btnCancel.Invoke(new MethodInvoker(SyncMethod));
                }
                else
                {
                    for (int i = 1; i < 100; i++)
                    {
                        backgroundWorker1.ReportProgress(i);
                        Thread.Sleep(50);
                    }
                }
    
            }

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    May 2006
    Posts
    426

    Re: Send bulk SMS progressbar and backgroundworker

    JMC, i got this working, but i had to look here and there. Some staff i included is not contained in your submission but the invoke methods were quite helpful. Saved me time. Thanks thou.
    Last edited by maps; Nov 6th, 2009 at 03:57 PM. Reason: thanks

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