My problem is that I want the form still display data when it increases but the form is blocked and I cannot do anything with it.
This is my code :
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
for (int i = 1; i < 11; i++)
richTextBox1.Text += "here" + i + "/n";
}
}
}
How I can prevent form from blocking?
private void Form1_Load(object sender, EventArgs e)
{
BackgroundWorker BWorker = new BackgroundWorker();
BWorker.DoWork += BWorker_DoWork;
BWorker.RunWorkerAsync();
}
void BWorker_DoWork(object sender, DoWorkEventArgs e)
{
// while(true) is meaningless.
for (int i = 1; i < 11; i++)
{
Action UpdateUI = () => { richTextBox1.Text += "here" + i + "/n"; };
this.BeginInvoke(UpdateUI);
}
}
Split your working cycle into steps by utilizing timer
private int _workStep;
private void button1_Click(object sender, EventArgs e)
{
_workStep = 0;
timerWork.Start();
}
private void timerWork_Tick(...)
{
switch(workStep)
{
case 0:
... // do something
if(something)
_workStep = 1;
case laststep:
timerWork.Stop();
}
}
or put work into thread (by using Thread, BackgroundWorker or Task), but then you must use Invoke/BeginInvoke when updating something in the user interface (accessing controls).
You can do this to get a responsive ui
delegate void DisplayInvoker(string text);
private void DisplayinRichTextbox(string text)
{
if (this.InvokeRequired)
this.BeginInvoke(new DisplayInvoker(DisplayinRichTextbox), text);
return;
}
richTextBox1.Text += text;
}
private void button1_Click(object sender, EventArgs e)
{
// some synchronization would have to be done kill old
// pool threads when the button is hit again
//
ThreadPool.QueueUserWorkItem((x) =>
{
while (true)
for (int i = 1; i < 11; i++)
DisplayinRichTextbox("here" + i + "/n");
});
}
Related
I want to create a C# form in which two text box show two different numbers.
After clicking on start button both numbers should start incrementing at same time should increment slowly so we can see them increment and clicking on stop button should stop increment.
Both text box are not related to each other any way.
public partial class Form1 : Form
{
Thread t1 = new Thread(new ThreadStart(increment1));
public static int fNumber = 0, sNumber = 0,flag = 0;
public Form1()
{
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
t1.Start();
}
private void button4_Click(object sender, EventArgs e)
{
}
private void number1_TextChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
public static void increment1()
{
Form1 frm = new Form1();
for (int i = fNumber;i<1000;i++)
{
frm.number1.Text = Convert.ToString(i);
}
}
}
public void Increment1()
{
for (int i = fNumber;i<1000;i++)
{
number1.Text = Convert.ToString(i);
number2.Text = Convert.ToString(i);
}
}
And just generally avoid static for threads. You can access your textboxes directly without the word this if you named your textboses number1 and number2. In a static method the variables need to be static aswell or you will get a compilation error.
For visibility, functions should have first letter in upper case. So you can distinguish them more easily from variables.
You are creating a new instance of Form1 which is wrong. Use the current Form1 that started the Thread.
Try
public partial class Form1 : Form
{
private Timer timer1;
public static int fNumber = 0, sNumber = 0,flag = 0;
public Form1()
{
timer1 = new Timer();
timer1.Interval = 1000;
timer1.Tick += timer1_Tick;
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void button4_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void number1_TextChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
int i = 0;
int.TryParse(this.number1.Text, out i);
i++;
if(this.number1.InvokeRequired)
{
this.number1.BeginInvoke((MethodInvoker) delegate()
{
this.number1.Text = Convert.ToString(i);
});
}
else
{
this.number1.Text = Convert.ToString(i);
}
}
}
For safety measures, check if invoking is required.
Replace this.number1.Text = Convert.ToString(i); with this block of code.
if(this.number1.InvokeRequired)
{
this.number1.BeginInvoke((MethodInvoker) delegate()
{
this.number1.Text = Convert.ToString(i);
});
}
else
{
this.number1.Text = Convert.ToString(i);
}
I have a function that displays numbers using a while loop but I want to stop execution of a while loop at random variable value using c# by clicking a button.
For Example:
private void FrqSent()
{
int i = 1;
while (i <= 5)
{
i = i + 1;
}
}
Here is a quick example on how you can use a Backgroundworker to accomplish your task:
public partial class Form1 : Form
{
private int i = 1;
public Form1()
{
InitializeComponent();
}
private void FrqSent()
{
while (i <= 500000000)
{
if (backgroundWorker1.CancellationPending)
{
break;
}
else
{
i = i + 1;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void button2_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
FrqSent();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show(i.ToString());
}
}
Just create a new Windows-Forms Project and add a backgroundworker object aswell as 2 buttons. You have to set the DoWork, RunWorkerCompleted and Click events manually.
Edit: Do not forget to set the BackgroundWorker`s WorkerSupportsCancellation property to true.
not very elegant but simple
public partial class Form1 : Form
{
private bool _stop;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
_stop = false;
FrqSent();
}
private void buttonStop_Click(object sender, EventArgs e)
{
_stop = true;
}
private void FrqSent()
{
int i = 1;
while (i <= 5000000 && !_stop)
{
i = i + 1;
Application.DoEvents();
}
}
}
In my application I need a progress bar to display the progress of a plant growing. This would be the code:
private static Timer farmProgress;
internal void initFarmProgTimer( int step, int max = 100 )
{
farmProgress = new Timer();
farmProgress.Tick += new EventHandler(farmProgress_Tick);
farmProgress.Interval = step; // in miliseconds
farmProgress.Start();
}
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value = increment;
}
}
Here the call of the initFarmProgTimer function:
public static System.Threading.Timer growTimer;
public static void InitGrowTimer(int time, string name)
{
growTimer = new System.Threading.Timer(growTimer_Finished, null, time, Timeout.Infinite);
plantActive = true;
Menu menu = new Menu();
menu.initFarmProgTimer(time / 100);
}
Note that the class where this function is called from is NOT a form but the class where the function is defined IS a form.
Does anybody know what my error is?
edit
here is the call for the InitGrowTimer function
switch ( index )
{
case 0:
currentPlant = wheat.name;
plantQ = printPlantDatas("wheat");
if (plantQ == true)
{
InitGrowTimer(wheat.time, wheat.name);
wheat.planted++;
}
break;
}
You are setting the value to the progress bar which will only set the progress to the current value. You have to increment it rather. I have added the pluss (+) sign for you
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value += increment;
}
}
It is not clear to me what is on a Form and what isn't but assuming this is on the Form:
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value = increment;
}
}
Change it to this so that you update the control from the UI thread:
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
this.Invoke(new Action(() => {
plantProgressBar.Value = increment;
}));
}
}
Update
My answer is wrong, I didn't expect this, but I created a Forms application and this worked fine to increment the progressbar:
public partial class Form1 : Form
{
private Timer farmProgress;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
farmProgress = new Timer();
farmProgress.Tick += farmProgress_Tick;
farmProgress.Interval = 1000; // in miliseconds
farmProgress.Start();
}
void farmProgress_Tick(object sender, EventArgs e)
{
progressBar1.Value++;
}
}
I have used Backgroundworkerclass to update my user interface element (Label). Please! Check my code below. It is working fine. But I am trying to replace Backgroundworkerclass and use simple worker thread to achieve the same goal. How can I achieve that? Any suggestion will be appreciated. Thanks
public void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = e.ProgressPercentage.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
else
label1.Text = "Busy Processing";
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
Thread.Sleep(100);
backgroundWorker1.ReportProgress(i);
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = e.ProgressPercentage.ToString();
}
delegate void DelegateDoWork(int number);
private void button1_Click(object sender, EventArgs e)
{
new Thread(DoWork).Start();
}
public void ProgressBar(int i)
{
if (label1.InvokeRequired)
{
var d = new DelegateDoWork(ProgressBar);
this.Invoke(d, i);
}
else
label1.Text = i.ToString();
}
public void DoWork()
{
for (int i = 0; i <= 100; i++)
{
Thread.Sleep(100);
ProgressBar(i);
}
}
i am trying to reload a web page 3 times using "axMozillaBrowser1(Mozilla ActiveX Control)"
but axMozillaBrowser1 control is not loading web page and it's waiting courser is blinking regular but browser control is not loading web page.
Please tell me how to use axMozillaBrowser1 control properly. Thanx in advance.
this is my program code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
progressBar1.Maximum = 3;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
do
{
axMozillaBrowser1.Navigate(textBox1.Text);
while(axMozillaBrowser1.ReadyState != MOZILLACONTROLLib.tagREADYSTATE.READYSTATE_COMPLETE)
{
Application.DoEvents();
if (axMozillaBrowser1.ReadyState == MOZILLACONTROLLib.tagREADYSTATE.READYSTATE_COMPLETE)
{
progressBar1.Value = progressBar1.Value + 1;
}
}
}while(progressBar1.Value != 3);
}
}
Why you want to Navigate 3 times ?
But my suggest is :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
progressBar1.Maximum = 3;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Value = 0;
axMozillaBrowser1.Navigate(textBox1.Text);
}
private void webBrowser2_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
if ( progressBar1.Value < 3 )
{
axMozillaBrowser1.Navigate(textBox1.Text);
progressBar1.Value = progressBar1.Value + 1;
}
}
}