Hi I am working on a TABU Search Algorithm and I need to access many functions to make it readable and easy I have used buttons and button.performClick();
Can someone let me know what I am doing wrong and how I can solve this issue?
Thank you
struct DataParameter
{
public int Process;
public int Delay;
}
private DataParameter _inputparameter;
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
lblBackGroundWorker.Text = string.Format("Processing...{0}%", e.ProgressPercentage);
progressBar1.Update();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
int process = ((DataParameter)e.Argument).Process;
int delay = ((DataParameter)e.Argument).Delay;
int index = 1;
try
{
//progressBar1.Value = 0;
//progressBar1.Update();
progressBar = 1;
//this.tmrTimeAndDate.Start();
Reset_Clear_For_New_Timetable();
sw_WhileLoop = Stopwatch.StartNew();
while (whileLoop > 0)
{
if (!backgroundWorker.CancellationPending)
{
backgroundWorker.ReportProgress(index++ * 100 / process, string.Format("Processing...{0}%", progressBar));
Thread.Sleep(delay); // used to simulate length of operation
if (whileLoop == 99)
{
Console.WriteLine("initial"); // initial
cmd_Start_Scheduling.PerformClick(); // create timetable
Get_Timetable_Send_To_Initial_DataTable(); // get timetable to the initial table
Get_Timetable_Send_To_Optimal_DataTable(); // get timetable to the optimal table
Calculate_Energy_High_Score_Initial();//calculate high score of initial solution
Calculate_Energy_High_Score_Optimal();//calculate high score of optimal solution
Reset_Clear_For_New_Timetable();
}
else
{
Console.WriteLine("not initial");// not initial
cmd_Start_Scheduling.PerformClick(); // create timetable
Fill_New_Solution();
Compare_Solution_Keep_The_Best();
Reset_Clear_For_New_Timetable();
}
whileLoop = whileLoop - 1;
progressBar = progressBar + 1;
}
}
sw_WhileLoop.Stop();
MessageBox.Show("Time taken: " + sw_WhileLoop.Elapsed.TotalSeconds.ToString() + " seconds \n Scheduling ended on step 7 because there was no Sup Class Left.");
MessageBox.Show("Done");
TimetableOutputQuestion TimetableOutputQuestionOpen = new TimetableOutputQuestion();
this.Hide();
TimetableOutputQuestionOpen.Show();
progressBar = 1;
whileLoop = 99;
}
catch (Exception ex)
{
backgroundWorker.CancelAsync();
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Timetable Scheduling Process Has Been Completed", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void CmdStartScheduling_Click(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
{
_inputparameter.Delay = 100;
_inputparameter.Process = 1200;
backgroundWorker.RunWorkerAsync(_inputparameter);
}
}
private void cmdStopScheduling_Click(object sender, EventArgs e)
{
if (backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync();
}
}
Add This code to the end in your while loop (inside the loop)
DateTime timeout = DateTime.Now.AddMilliseconds(50);
while (DateTime.Now < timeout) Application.doEvents;
it should do the trick.
Good luck
Related
I am trying to use a timer to achieve a sort of old animation used in the past to show that a process is running.
The way I would like to do that is by adding dots to a sentence (in a label control), for example:
"Process is running." to "Process is running.." and "Process is running..." with a limit of 3 dots and then revert back to a single dot.
I am not sure as to the fact using a timer here would be the best choice, but I thought it should work fine for such a simple example.
The code I used is as follows:
public string InitialProcessText;
private void StartBtn_Click(object sender, EventArgs e)
{
if(fileName != "No file selected")
{
ValidationLbl.Text = null;
ProcessLbl.Text = "Application is now running.";
//InitialProcessText = ProcessLbl.Text;
ProcessTimer.Start();
}
else
{
ValidationLbl.Text = "No file was added";
}
}
private void StopBtn_Click(object sender, EventArgs e)
{
ProcessTimer.Stop();
}
private void ProcessTimer_Tick(object sender, EventArgs e)
{
_ticks++;
//For every two ticks, ProcessLbl.Text = InitialProcessText
ProcessLbl.Text += ".";
}
What could I add to set a limit of adding 2 dots and then remove the dots and add dots again (I would assume to do this in the ProcessTimer_Tick method)?
You can just use your _ticks variable:
private readonly int _ticksPerUpdate = 2;
private readonly int _maxNumberOfDots = 3;
private void ProcessTimer_Tick(object sender, EventArgs e)
{
_ticks++;
if(_ticks == (_ticksPerUpdate * (_maxNumberOfDots + 1)))
{
_ticks = 0;
ProcessLbl.Text = InitialProcessText;
}
else if(_ticks % _ticksPerUpdate == 0)
{
ProcessLbl.Text += ".";
}
}
Remember to reset the ticks counter every time you start the timer:
private void StartBtn_Click(object sender, EventArgs e)
{
if(fileName != "No file selected")
{
ValidationLbl.Text = null;
ProcessLbl.Text = "Application is now running.";
InitialProcessText = ProcessLbl.Text;
// reset the variable
_ticks = 0
ProcessTimer.Start();
}
else
{
ValidationLbl.Text = "No file was added";
}
}
I assume that _ticks counts the number of ticks. You could then go :
if(ticks%3 == 0)
{
ProcessLbl.Text = "Application is now running."
}
else
{
ProcessLbl.Text+=".";
}
Then, at 1st tick, 1%3=1 so it adds a dot, at 2nd tick, 2%3=2 so it adds a dot and 3rd tick, 3%3=0, so it gets back to original.
Just because...here's another approach:
private void ProcessTimer_Tick(object sender, EventArgs e)
{
ProcessLbl.Text = ProcessLbl.Text.EndsWith("...") ? ProcessLbl.Text.TrimEnd(".".ToCharArray()) + "." : ProcessLbl.Text + ".";
}
How could I show a progress bar when moving a file?
Currently I've got this:
private void btnMoveFile_Click(object sender, EventArgs e)
{
try
{
if (pathFrom != null && pathTo != null)
{
if (txtRename.Text != null)
{
pathTo = pathTo + "\\" + txtRename.Text;
}
else
{
pathTo = pathTo + "\\" + Path.GetFileName(pathFrom);
}
File.Move(pathFrom, pathTo);
}
else
{
MessageBox.Show("Kies eerst een bestand.");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
// Wait 100 milliseconds.
Thread.Sleep(100);
// Report progress.
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
// Set the text.
this.Text = e.ProgressPercentage.ToString();
}
But because File.Move(pathFrom, pathTo); is not a loupe I've got no Idea how to do this.
Consider using the SHFileOperation API from shell32.
A working solution is described in this answer: How to bring up the built-in File Copy dialog?
It works for copy as well as for move and delete.
I'm trying to make a Tamagochi but I've ran into a problem. I have a Progressbar with a max value of 300. Every 5-8 seconds the Progressbar empties a bit. Once it gets below 250 you're allowed to sleep.
Here is the code i have so far:
private void BtnSleep_Click(object sender, EventArgs e)
{
if (PgbSleep.Value <= 250)
{
int temp = PgbSleep.Maximum - PgbSleep.Value;
if (temp + PgbSleep.Value >= 300)
{
Timer2.Stop();
Thread.Sleep(20000);
PgbSleep.Value = 300;
Timer2.Start();
}
}
else
{
MessageBox.Show("Your pokemon is not tired enough to sleep! try playing with it");
}
}
I'm trying to find a replacement for the
Thread.Sleep(20000);
But dont know what to use. Any help would be much appreciated!
The
Thread.Sleep(20000);
Is supposed to be a cooldown, once its completed the user is allowed to sleep again if the requirements are met.
Try using a timer:
Timer sleepTimer = new Timer(20000); //Creates a timer for sleeping
public MyClass()
{
sleepTimer.Elapsed += new EventHandler((s, e) => WakeUp());
}
private void BtnSleep_Click(object sender, EventArgs e)
{
if (PgbSleep.Value <= 250)
{
int temp = PgbSleep.Maximum - PgbSleep.Value;
if (temp + PgbSleep.Value >= 300)
{
Timer2.Stop();
sleepTimer.Start();
}
}
else
{
MessageBox.Show("Your pokemon is not tired enough to sleep! try playing with it");
}
}
private void WakeUp()
{
PgbSleep.Value = 300;
Timer2.Start();
}
I am calling this code inside a for loop and I need to do this since progress depends on this for loop value.
bgworker1.ReportProgress(k * count);
But I receive an exception:
this operation has already had operation completed called on it and further calls are illegal
How can I solve this??
Edit:
private void bgworker1_DoWork(object sender, DoWorkEventArgs e)
{
for (k = 1; k <= tcount; k++)
{
bgworker1.ReportProgress(k * count);
}
}
private void bgworker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void bgworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bgworker1.ReportProgress(k * count);
}
One way you can tackle this is reporting progress in a exclusive for-loop for this only task, like this
private void bgworker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 100; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
//Insert your logic HERE
worker.ReportProgress(i * 1);
}
}
}
I am designing a program that depends on monitoring the battery level of the computer.
This is the C# code I am using:
PowerStatus pw = SystemInformation.PowerStatus;
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
My failed attempt of the while statement, it uses all the CPU which is undesirable.
int i = 1;
while (i == 1)
{
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
}
How do I monitor this constantly with an infinite loop so that when it reaches 75% it will execute some code.
Try Timer:
public class Monitoring
{
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
public Monitoring()
{
timer1.Interval = 1000; //Period of Tick
timer1.Tick += timer1_Tick;
}
private void timer1_Tick(object sender, EventArgs e)
{
CheckBatteryStatus();
}
private void CheckBatteryStatus()
{
PowerStatus pw = SystemInformation.PowerStatus;
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
}
}
UPDATE:
There is another way to do your task complete. You can use SystemEvents.PowerModeChanged.
Call it and wait for changes, monitor the changes occured then do your stuff.
static void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
{
if (e.Mode == Microsoft.Win32.PowerModes.StatusChange)
{
if (pw.BatteryLifeRemaining >= 75)
{
//Do stuff here
}
}
}
While loop will cause your UI to response poor and the application will get crashed. You can solve this by using many ways. Please check out the below code snippet will help your needs.
public delegate void DoAsync();
private void button1_Click(object sender, EventArgs e)
{
DoAsync async = new DoAsync(GetBatteryDetails);
async.BeginInvoke(null, null);
}
public void GetBatteryDetails()
{
int i = 0;
PowerStatus ps = SystemInformation.PowerStatus;
while (true)
{
if (this.InvokeRequired)
this.Invoke(new Action(() => this.Text = ps.BatteryLifePercent.ToString() + i.ToString()));
else
this.Text = ps.BatteryLifePercent.ToString() + i.ToString();
i++;
}
}
BatteryChargeStatus.Text = SystemInformation.PowerStatus.BatteryChargeStatus.ToString();
BatteryFullLifetime.Text = SystemInformation.PowerStatus.BatteryFullLifetime.ToString();
BatteryLifePercent.Text = SystemInformation.PowerStatus.BatteryLifePercent.ToString();
BatteryLifeRemaining.Text = SystemInformation.PowerStatus.BatteryLifeRemaining.ToString();
PowerLineStatus.Text = SystemInformation.PowerStatus.PowerLineStatus.ToString();
If you want to perform some operation just convert these string values into the integer.