|
-
Nov 5th, 2009, 03:23 PM
#1
Thread Starter
Hyperactive Member
[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
-
Nov 5th, 2009, 08:32 PM
#2
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.
-
Nov 5th, 2009, 11:12 PM
#3
Thread Starter
Hyperactive Member
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.
-
Nov 5th, 2009, 11:39 PM
#4
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.
-
Nov 6th, 2009, 12:14 AM
#5
Thread Starter
Hyperactive Member
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!
-
Nov 6th, 2009, 12:32 AM
#6
Thread Starter
Hyperactive Member
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);
}
}
}
-
Nov 6th, 2009, 12:49 AM
#7
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.
-
Nov 6th, 2009, 01:27 AM
#8
Thread Starter
Hyperactive Member
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;
}
-
Nov 6th, 2009, 01:33 AM
#9
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.
-
Nov 6th, 2009, 01:57 AM
#10
Thread Starter
Hyperactive Member
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);
}
}
}
-
Nov 6th, 2009, 02:00 PM
#11
Thread Starter
Hyperactive Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|