• ### Popular Now

• 15
• 15
• 11
• 9
• 10

#### Archived

This topic is now archived and is closed to further replies.

This topic is 5391 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

		private void cmnuReports_LabSumByProcChildren_Click(object sender, System.EventArgs e)
{
}
private void DoStuff()
{
for(int i = 0; i <= 100; i += 20)
{
int oldticks = System.Environment.TickCount + 1000;
for(int ticks = System.Environment.TickCount; ticks < oldticks; ticks = System.Environment.TickCount)
{
}
}
}
	public class frmLoading : System.Windows.Forms.Form
{
private System.Windows.Forms.Label lblText;
private System.Windows.Forms.ProgressBar progBar;
private System.ComponentModel.Container components = null;

{
InitializeComponent();
}

{
this.lblText.Text = Text;
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

public void UpdateProgress(float percent)
{
this.progBar.Value = (int)(percent * 100);
this.progBar.Update();
this.Refresh();
}
}
If anyone can supply me with information on trying to acheive this feat, please share. Thank you.

##### Share on other sites
It is generally a bad idea to base your progress bar off of an amount of time instead of amount of work done.

In general, I''d make a work estimate (say, 5,000 records) and call a friend method on the progress bar form with updates every 100 or so. Have the friend method use the Synchronized attribute so that only one call can be occuring at a time.

Then, have your progress bar update itself based off of timer events.

That way, you won''t encounter problems when faster computers come along and blow your original time estimate out of the water.

##### Share on other sites
ummm, yeah, the function I posted was just a test to see if my updating actually worked. I will be basing my timing method off of work done.

Anyway, Im such a newb, I finally found out what was wrong:
loading.UpdateProgress((i/100));

The input to that function accepts a float telling it the percent that the progress bar should be (0 being no bar, 1.0 being full) but that calculation kept returning the integer 0 so the bar wasnt moving.

##### Share on other sites
You''re calling the method of a control (loading.UpdateProgress()) from a thread other than the thread that created the control which is not good. You need to use Control.Invoke() to marshal the call to the control''s thread.
// delegate declarationdelegate void UpdateLoadFormDelegate(float i);...private void DoStuff(){    UpdateLoadFormDelegate updateProgress = new UpdateLoadFormDelegate(loading.UpdateProgress);    ...}

Then, in the DoStuff() method, replace the call to loading.UpdateProgress() with the Control.Invoke() method:
loading.Invoke(updateProgress, new object[] { i/100f });

Is there any special reason you''re calling Thread.CurrentThread.Abort() at the end of this function?

##### Share on other sites
quote:
Original post by noparity
You''re calling the method of a control (loading.UpdateProgress()) from a thread other than the thread that created the control which is not good. You need to use Control.Invoke() to marshal the call to the control''s thread.
// delegate declarationdelegate void UpdateLoadFormDelegate(float i);...private void DoStuff(){    UpdateLoadFormDelegate updateProgress = new UpdateLoadFormDelegate(loading.UpdateProgress);    ...}

Then, in the DoStuff() method, replace the call to loading.UpdateProgress() with the Control.Invoke() method:
loading.Invoke(updateProgress, new object[] { i/100f });

I dont understand why it is bad to do what I am doing? Using your method I have to create another global varaible, the loading Form''s UI isnt updated properly, and I cannot position the window while the "working" thread is doing the calculations.
quote:
Is there any special reason you''re calling Thread.CurrentThread.Abort() at the end of this function?

No. I just wasnt sure if I had to or not so I chose to do it to be safe. (I''m guessing I dont need to, do I?)

##### Share on other sites
quote:

I dont understand why it is bad to do what I am doing? Using your method I have to create another global varaible, the loading Form''s UI isnt updated properly, and I cannot position the window while the "working" thread is doing the calculations.

Windows Forms applications use the single-threaded apartment (STA) model (in fact, native Win32 windows are apartment-threaded as well). In short, the STA model implies that a window can be created on any thread, but all function calls to that window must occur on the thread that created the window.

The problems that you''re mentioning make me think that you have not implemented your delegate properly. My example is also part to blame as it wasn''t very explict.

The delegate declaration is placed in the class that will be creating the Loading Form (this was not clear in my last example):
public class MainForm : System.Windows.Forms.Form{    // here''s our Load Form    LoadForm theForm = null;    // delegates to call to the Load Form from another thread    private delegate void UpdateLoadFormDelegate(float i);    private delegate void UpdateFinishedDelegate();    ...    private void button1_Click(object sender, System.EventArgs e)    {        this.theForm = new LoadForm();        System.Threading.Thread loadThread = new Thread(new ThreadStart(this.DoStuff);        this.theForm.Show();        loadThread.Start();    }    private void DoStuff()    {            UpdateLoadFormDelegate updateProgress = new UpdateLoadFormDelegate(theForm.UpdateProgress);        for (...)        {            this.theForm.Invoke(updateProgress, new object[] { i/100f});        }        UpdateFinishedDelegate finished = new UpdateFinishedDeleate(this.theForm.Close);        this.theForm.Invoke(finished);    }    ....}

This is how I''ve implemented it and it works great. You''ll also notice that I''ve added a new delegate to close the Load Form (don''t know how I missed it the first time around ).
quote:

No. I just wasnt sure if I had to or not so I chose to do it to be safe. (I''m guessing I dont need to, do I?)

Calling CurrentThread.Abort() will raise a ThreadAbortException() which will incur some overhead. Just let the function exit normally and the worker thread will terminate.

##### Share on other sites
Thanks noparity. Im new to multi threading and havnt used delagates before so I just figured if my way worked, then it was ok.

I am currently implementing the loading form the right way (your way) and will see how it goes.

Thanks again.