Application memory usage and looping - c#

So I am trying to make a bot application, trying to see how I can do certain things in c#. I am not trying to cheat or so, it is a mobile game that I am running on a emulator. This is not an application that I am trying to sell or in any way profit from, this is simply a task for me to learn how to do these kind of things.
Any how, when I launch the application the memory goes up to 16 mb instantly, also I am trying to make a loop until a stop button has been clicked.
I make functions for every single action and I am using a timer to run all the functions to scan if a pixel gets detected, but the application is running slowly and taking up a lot of memory, I feel like this kind of "looping" is not the proper way to do this kind of action, I have tried the while method as well.
Anybody who is willing to tell me what I am doing?
Pastebin
private void timer1_Tick(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
// Checking if we entered Dragon's B10
if (inDungeon == false)
{
GoToDungeon();
}
// Starting battle
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2078, 61); // 0xF1EECF
if (autoSumPoint == 0xF1EECF)
{
StartBattle();
}
else
{
GoToDungeon();
}
// Starting auto-play
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2296, 969); // 0xFFFFFF
if (autoSumPoint == 0xFFFFFF)
{
AutoCheck();
}
// Starting battle
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2755, 489); // 0xF1EECF
if (autoSumPoint == 0xF1EECF)
{
PauseCheck();
}
// Checking for defeat
if (defeatChecked == false)
{
DefeatCheck();
}
// Checking for defeat
if (defeatChecked == false)
{
DefeatCheck();
}
// Checking for victory
if (victoryChecked == false)
{
VictoryCheck();
}
// Checking for replay
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2602, 587); // 0xF3C761
if (autoSumPoint == 0xF3C761)
{
ReplayCheck();
}
// Checking for refill
if (energyRefilled == false)
{
RefillCheck();
}
}
}

I would consider changing the delay between each tick of the timer, so that it doesn't burn up your CPU.
private void timer1_Tick(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
// Checking if we entered Dragon's B10
if (inDungeon == false)
{
GoToDungeon();
}
// Starting battle
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2078, 61); // 0xF1EECF
if (autoSumPoint == 0xF1EECF)
{
StartBattle();
}
else
{
GoToDungeon();
}
// Starting auto-play
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2296, 969); // 0xFFFFFF
if (autoSumPoint == 0xFFFFFF)
{
AutoCheck();
}
// Starting battle
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2755, 489); // 0xF1EECF
if (autoSumPoint == 0xF1EECF)
{
PauseCheck();
}
// Checking for defeat
if (defeatChecked == false)
{
DefeatCheck();
}
// Checking for defeat
if (defeatChecked == false)
{
DefeatCheck();
}
// Checking for victory
if (victoryChecked == false)
{
VictoryCheck();
}
// Checking for replay
autoSumPoint = AutoIt.AutoItX.PixelGetColor(2602, 587); // 0xF3C761
if (autoSumPoint == 0xF3C761)
{
ReplayCheck();
}
// Checking for refill
if (energyRefilled == false)
{
RefillCheck();
}
}
System.Threading.Thread.Sleep(1000)//causes it to wait 1 second after each tick before the next one to reduce CPU usage
}
See if that helps you!
Techcraft7 :)

Related

While Loop Function after a button is pressed and stop looping when another button is pressed C#

In my Windorm Form application, I have two buttons which a loop function will begin to do the work when button1 is pressed and stop executing after button2 is pressed. How could i do this to prevent my GUI from non-responsive.
How could i insert command while(button2.clicked != true)
My code for button 1:
private async void EmoStart_Click_1(object sender, EventArgs e)
{
//var repeat = "true";
string imageFilePath = "C:\\Users\\Administrator\\source\\repos\\FaceDetection\\FaceDetection\\test3.jpg";
while (VoiceStart_Click_2 != "true")
{
var image = pictureBox1.Image;
image = resizeImage(image, new Size(1209, 770));
image.Save(imageFilePath);
if (File.Exists(imageFilePath))
{
var Emo = await FaceEmotion.MakeAnalysisRequest(imageFilePath);
if (Emo[0].FaceAttributes.Emotion.Anger >= 0.5)
{
EmoBox.Text = "Anger, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Contempt >= 0.5)
{
EmoBox.Text = "Contempt, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Disgust >= 0.5)
{
EmoBox.Text = "Disgust, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Fear >= 0.5)
{
EmoBox.Text = "Fear, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Happiness >= 0.5)
{
EmoBox.Text = "Happiness, Good Driving Condition";
}
else if (Emo[0].FaceAttributes.Emotion.Neutral >= 0.5)
{
EmoBox.Text = "Neutral, Good Driving Condition";
}
else if (Emo[0].FaceAttributes.Emotion.Sadness >= 0.5)
{
EmoBox.Text = "Sadness, Bad Driving Condition, Rock Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Surprise >= 0.5)
{
EmoBox.Text = "Happiness, Bad Driving Condition, Soft Music will be played";
}
else
{
EmoBox.Text = "Stable Condition, Good Driving Condition";
}
}
}
While for my button2 code:
private async void VoiceStart_Click_2(object sender, EventArgs e)
{
string command = await Voice.RecognizeSpeechAsync();
VoiceBox.Text = command;
}
Thank you!
You have to run your loop in a separate thread. For example, you can run it asynchroniously. Something like this:
// start the loop
private async void button1_Click(object sender, EventArgs e)
{
LoopStopped = false;
await StartLoopAsync();
}
// put yor while loop here
private Task StartLoopAsync()
{
return Task.Run(() =>
{
while (LoopStopped == false)
{
var date = DateTime.Now;
System.Diagnostics.Debug.WriteLine(date);
}
System.Diagnostics.Debug.WriteLine("Thread stopped.");
});
}
// stop the loop
private void button2_Click(object sender, EventArgs e)
{
LoopStopped = true;
}
Where LoopStopped is global boolean variable.
All the operations you put into the EmoStart_Click_1 is running synchronously, except:
FaceEmotion.MakeAnalysisRequest(imageFilePath)
thus the interface (UI) is frozen.
It is not enough to change the signature of the method to async as you did. You must tell the compiler, which other parts should be awaited. You want your whole while function async!
private async void EmoStart_Click_1(object sender, EventArgs e)
{
EmoStart.Enabled = false; //I assume EmoStart is the name of your button
await Task.Factory.StartNew(Loop);
EmoStart.Enabled = true;
}
private void Loop() //since this method doesn't have async in its signature "var Emo = await FaceEmotion.MakeAnalysisRequest(imageFilePath);" won't compile, so you should change to the synchronous equivalent "var Emo = FaceEmotion.MakeAnalysisRequest(imageFilePath).Result;" --> note that it won't block due to "Task.Factory.StartNew".
{
string imageFilePath = "C:\\Users\\Administrator\\source\\repos\\FaceDetection\\FaceDetection\\test3.jpg";
while (...)
{
// do your stuff
}
Then you can decide how you want to cancel the while loop.
Option 1.: you could use a global, bool variable:
private bool emotionsShouldBeProcessed;
and you set it true in EmoStart_Click_1 and false like this:
private async void VoiceStart_Click_2(object sender, EventArgs e)
{
VoiceStart.Enabled = false;
emotionsShouldBeProcessed = false;
// start and await voice stuff
VoiceStart.Enabled = true;
}
Option 2.: you could use a CancellationToken to track if cancel is necessary.
CancellationTokenSource cSource;
private async void EmoStart_Click_1(object sender, EventArgs e)
{
EmoStart.Enabled = false;
cSource = new CancellationTokenSource();
await Task.Factory.StartNew(() => Loop(cSource.Token));
EmoStart.Enabled = true;
}
private void Loop(CancellationToken cToken)
{
string imageFilePath = "C:\\Users\\Administrator\\source\\repos\\FaceDetection\\FaceDetection\\test3.jpg";
while (true)
{
if (cToken.IsCancellationRequested)
break;
// otherwise do your stuff
}
// some clean up here if necessary
}
private async void VoiceStart_Click_2(object sender, EventArgs e)
{
VoiceStart.Enabled = false;
cSource.Cancel();
VoiceStart.Enabled = true;
}
So far so good! But your code will crash
It will crash whenever you want to set EmoBox.Text as this can happen only on the UI thread. To avoid this, you need to ask the UI thread to interrupt until Textbox/Label/etc operations are going on, like this:
this.Invoke((MethodInvoket)delegate
{
EmoBox.Text = "...";
});
Edit:
I would also check the Emo array whether it is empty since face- and emotion recognitions not always succeeds! Thus, Emo[0] can result in "Index was out of range" exception. Following code makes sure it isn't empty:
var Emo = ...;
if (Emo.Length > 0)
{
if (...)
// use Emo[0]
else if (...)
// use Emo[0] differently
}
Let me know if there is anything unclear.
You can create a bool variable and make the loop while your variable is true.
So set the variable to true, when button1 is clicked.
Then your while would look like this:
while(myBoolVariable)
And when button2 is clicked you can change the value to false and the while will stop.
You can use a global variable(bool is a good choice)
when VoiceStart_Click_2 change the variable
and do check the variable when EmoStart_Click_1 is clicked
if (variable==true)
{
var Emo = await FaceEmotion.MakeAnalysisRequest(imageFilePath);
if (Emo[0].FaceAttributes.Emotion.Anger >= 0.5)
{
EmoBox.Text = "Anger, Bad Driving Condition, Soft Music will be played";
}
...
}

Is it possible to have a while loop slowed?

Rewrite: I'm writing a program to get a better understanding of C# and taking user input in. Right now I'm using WFA in C# with a textbox where I put the text of what I want pasted/typed out. Then I have two other boxes that have an interval input and a amount input. Everything worked perfectly fine until I added the amount input, I've added a while loop to a timer that is used to type/paste the text. However, for some reason that I'm not sure of.. The program disregards any input for the interval.
I have it basically setup like this
private void timerPaste_Tick(object sender, EventArgs e)
{
interval = Int32.Parse(interNum.Text);
timerPaste.Interval = interval;
if (typeModebool == true && pasteModebool == false)
{
while (amount > 0) //Need to find a way to make GUI responsive during while loop.
{
SendKeys.Send(textBox1.Text);
SendKeys.Send("{Enter}");
amount--;
}
timerPaste.Enabled = false;
amount = Int32.Parse(amountSetBox.Text);
}
if (pasteModebool == true && typeModebool == false)
{
while (amount > 0) //Need to find a way to make GUI responsive during while loop.
{
Clipboard.SetText(textBox1.Text);
SendKeys.Send("^{c}");
SendKeys.Send("^{v}");
SendKeys.Send("{Enter}");
amount--;
}
timerPaste.Enabled = false;
amount = Int32.Parse(amountSetBox.Text);
}
}
something like that..?
timerPaste.Elapsed += OnTickEvent;
private async void OnTickEvent(Object source,EventArgs e)
{
interval = Int32.Parse(interNum.Text);
timerPaste.Interval = interval;
if (typeModebool == true && pasteModebool == false)
{
while (amount > 0) //Need to find a way to make GUI responsive during while loop.
{
SendKeys.Send(textBox1.Text);
SendKeys.Send("{Enter}");
amount--;
}
timerPaste.Enabled = false;
amount = Int32.Parse(amountSetBox.Text);
}
if (pasteModebool == true && typeModebool == false)
{
while (amount > 0) //Need to find a way to make GUI responsive during while loop.
{
Clipboard.SetText(textBox1.Text);
SendKeys.Send("^{c}");
SendKeys.Send("^{v}");
SendKeys.Send("{Enter}");
amount--;
}
timerPaste.Enabled = false;
amount = Int32.Parse(amountSetBox.Text);
}
}
I actually was able to fix this, the problem was that the while loop listened to the timer the first time, then after that just started going off on it's own. I switched it to a if, with an else statement and everything works as intended now.
int i = 0;
private void timerPaste_Tick(object sender, EventArgs e)
{
if (typeModebool == true && pasteModebool == false) //Check what mode is being used
{
if (i < amount) //If runs until i == amount
{
SendKeys.Send(textBox1.Text);
SendKeys.Send("{Enter}");
amount--;
}
else
{
timerPaste.Enabled = false;
}
}
if (pasteModebool == true && typeModebool == false)
{
if (i < amount)
{
Clipboard.SetText(textBox1.Text);
SendKeys.Send("^{c}");
SendKeys.Send("^{v}");
SendKeys.Send("{Enter}");
amount--;
}
else
{
timerPaste.Enabled = false;
}
}
}

Music player freeze a bit when pressing next button too fast

Based on:
C# windows form & using WMPLib
The Problem:
when pressing next or prev button too fast, the apps will freeze a bit (uncontrollable).
The Code:
private void next_event()
{
_paused = false;
if (list[current_index].Rows.Count != 0 && _playing == true)
{
if (option.random.Checked == true)
{
nextRandom(1);
}
else if (option.order.Checked == true)
{
if (list[current_index].Rows.IndexOf(_musicData[_NowPlaying]) == list[current_index].Rows.Count - 1)
{
setNowPlaying((Guid)list[current_index].Rows[0].Cells["Key"].Value);
}
else
{
setNowPlaying((Guid)list[current_index].Rows[list[current_index].Rows.IndexOf(_musicData[_NowPlaying]) + 1].Cells["Key"].Value);
}
}
seek_bar.Value = 0;
play();
}
}
private void prev_event()
{
_paused = false;
if (list[current_index].Rows.Count != 0 && _playing == true)
{
if (option.random.Checked == true)
{
nextRandom(2);
}
else if (option.order.Checked == true)
{
if (list[current_index].CurrentRow.Index == 0)
{
setNowPlaying((Guid)list[current_index].Rows[list[current_index].Rows.Count - 1].Cells["Key"].Value);
}
else
{
setNowPlaying((Guid)list[current_index].Rows[list[current_index].Rows.IndexOf(_musicData[_NowPlaying]) - 1].Cells["Key"].Value);
}
}
seek_bar.Value = 0;
play();
}
}
private void play() // play
{
button3.Text = "Pause";
dmp_status.Text = "Playing...";
_paused = false;
if (list[current_index].Rows.Count != 0)
{
if (File.Exists(_musicData[_NowPlaying].Cells["FileLocation"].Value.ToString()))
{
if (_playing == true) wmp.controls.stop();
if(wmp != null) wmp.close();
wmp = new WMPLib.WindowsMediaPlayer();
wmp.PlayStateChange += new WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(PlayStateChange);
seek_bar.Value = 0;
setNowPlayingLabel(_musicData[_NowPlaying]);
if (!_musicData.ContainsKey(_LastPlaying)) _LastPlaying = Guid.Empty;
setNowPlayingColor(_musicData[_LastPlaying],_musicData[_NowPlaying]);
//wmp.URL = list[current_index].CurrentRow.Cells["FileLocation"].Value.ToString();
wmp.URL = _musicData[_NowPlaying].Cells["FileLocation"].Value.ToString();
wmp.controls.play();
wmp.settings.rate = wmp_rate;
wmp.settings.volume = volume_pos;
if (_playing == false) _playing = true;
}
else
{
next_event();
}
}
}
The Question:
I have hard time figuring why they need a delay(freeze) before playing each music, this making a problem when user press next button consecutively.
I think it is due to reentry. Happened when subsequent events are fire while the first event hasn't complete. To prevent this:
// add this line to your class member
private Object syncRoot = new Object();
// add this block to your next_event() method
if (!Monitor.TryEnter(syncRoot)) return;
try {
// add your existing code here
}
finally {
Monitor.Exit(syncRoot);
}

using PlayStateChange event to loop the song in MediaPlayer

I'm trying to implement the code that will loop current song countless times.
That's my code:
private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if (e.newState == 8) // media ended
{
if (repeat)
{
axWindowsMediaPlayer1.Ctlcontrols.currentPosition = 0;
//axWindowsMediaPlayer1.Ctlcontrols.previous();
//axWindowsMediaPlayer1.Ctlcontrols.playItem(axWindowsMediaPlayer1.Ctlcontrols.currentItem);
}
}
}
setting currentPosition = 0 is working fine if I debug the code on the next line.
But after debug - new event is triggered(event 9(Transitioning) followed by event 3(Playing)) and the next song starts to play!
how do I prevent this from happening?
basically that is what happening right now:
event 8 triggered (Media End)
set position 0
event 9 triggered (Transitioning)
event 3 triggered (Playing)
Edit: after messing around with my code I have finally managed to break the chain of Event changes.
public bool ended = false;
public WMPLib.IWMPMedia latest_song;
private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if (ended)
{
axWindowsMediaPlayer1.Ctlcontrols.playItem(latest_song);
ended = false;
return;
}
if (e.newState == 8) // media ended
{
if (repeat)
{
ended = true;
latest_song = axWindowsMediaPlayer1.Ctlcontrols.currentItem;
}
}
}
I don't know if the code can get any better than this..
bool ended = false;
bool skipnext = false;
bool skipnextnext = false;
bool skipextra = false;
private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if (ended)
{
skipnext = true;
ended = false;
axWindowsMediaPlayer1.Ctlcontrols.playItem(latest_song);
return;
}
if (e.newState == 6) // buffering
{
skipextra = true;
}
if (e.newState == 8) // media ended
{
if (repeat)
{
if (currect_album.Songs.Count < 2) { return; }
ended = true;
latest_song = current_song;
return;
}
}
else if (e.newState == 3) // playing
{
// these "skips" are necessary for scenario: "repeat: on", "click: next"
if (skipnext) { skipnext = false; skipnextnext = true; return; }
if (skipnextnext) { skipnextnext = false; return; }
// Buffering adds 1 more skip! Ask Microfost why ;)
if (skipextra) { skipextra = false; return; }
current_song = axWindowsMediaPlayer1.Ctlcontrols.currentItem;
// your stuff
}
}
the first solution worked fine for half a day ;)
the second solution worked for "repeat", but did not work in case if user clicked "next"
the third and final (I hope) solution finally works in situations when "repeat" is needed, plus it skips the song if "next/prev" command is triggered!
the fourth edition! added extra "skip" if buffering kicked in.. Buffering messed up my code a bit, but now it's all working. Additionally, I've added "1 song in a playlist" checker.
P.S. Microsoft coders - if you see this post - please, add "on_next" and "on_previous" status! Thanks

Check window for focus-Password Generator C#

For my end of year project I am creating a password generator where you generate a password, then you can choose whether or not you want to store it in a local compact DB(.sdf). I am working on the GUI at the moment. I am creating a strength bar for passwords but the problem is that I can't seem to have it update the strength bar without first moving the slider. Let me show you example of what I am talking about. I was wondering if I could do this with code or with action events. Tell me what you think. Below is some code for the GUI designer. Do you think this is a good idea or would there be a better way? The focus idea came from if the window has focus it would keep checking the options and see if anything has changed. Video: http://youtu.be/ihSeKbsL55M
namespace PasswordGenerator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void fileToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void quitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void quitToolStripMenuItem1_Click(object sender, EventArgs e)
{
this.Close();
}
private void bcopy_Click(object sender, EventArgs e)
{
if (passwordGenBox.Text.Length != 0)
{
Clipboard.SetText(passwordGenBox.Text);
}
else
{
MessageBox.Show("No Password Generated.", "Copy Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void bclear_Click(object sender, EventArgs e)
{
passwordGenBox.Text = "";
}
private void lengthSlider_Scroll(object sender, EventArgs e)
{
sliderLength.Text = lengthSlider.Value.ToString();
int str = lengthSlider.Value;
bool scheck = symCheck.Checked;
bool ncheck = numbersCheck.Checked;
//1-10 no symbols or numbers
if (str > 0 && str <= 10)
{
strLabel.Text = "Week";
}
//1-10 symbols no numbers
if (str > 0 && str <= 10 && scheck == true && ncheck == false)
{
strLabel.Text = "Alright";
}
//1-10 no symbols but numbers
if (str > 0 && str <= 10 && scheck == false && ncheck == true)
{
strLabel.Text = "Week";
}
//1-10 symbols & numbers
if (str > 0 && str <= 10 && scheck == true && ncheck == true)
{
strLabel.Text = "Okay";
}
}
private void bgen_Click(object sender, EventArgs e)
{
int pwlength = lengthSlider.Value;
bool symbols = false;
bool numbers = false;
if (symCheck.Checked && numbersCheck.Checked)
{
symbols = true;
numbers = true;
}
else if (symCheck.Checked && numbersCheck.Checked == false)
{
symbols = true;
numbers = false;
}
else if (symCheck.Checked == false && numbersCheck.Checked)
{
symbols = false;
numbers = true;
}
else
{
symbols = false;
numbers = false;
}
Generator gen = new Generator(pwlength, symbols, numbers);
}
}
}
Well, it's quite difficult to understand what you're actually asking here but the reason your ProgressBar isn't updating is that you're not actually telling it to update unless you move the slider.
Notice how you have all your logic for whether the password is "alright, weak or okay" on the Slide event of your "lengthSlider" component. However, nowhere in that code do you set the value of the ProgressBar - that appears to be done on the "bgen_Click" event which I assume is the generate password button?
In order to update the GUI when you operate the individual controls you need to call the appropriate code. I would suggest you put all your logic into meaningful functions and call them as needed.
Personally I'd have something along these lines:
GetPasswordStrengthString(); - check for symbols and numbers checkbox.checked and the length to return an appropriate string for the "strLabel" label.
CalculateStrengthBarLength(); - all your logic to determine the length of the ProgressBar
These would then be called wherever you want them to take effect. For example, on the CheckedChanged event of the symbols and numbers checkboxes as when that changes you want to see it reflected in the ProgressBar.

Categories