Application is not responding - c#

What the application should do
This application should take the input of time (seconds, minutes and hours) and shutdown the computer after that time. It should also update the text box with how long left until the computer has shut down.
What the application actually does
I had an issue that I 'fixed' where the called ac across threads weren't safe, so I fixed it and I don't get that error now. However, the updateThread doesn't update and print the time left; and the text box doesn't get "test" appended to it. The UI also becomes Not Responding. Any help would be much appreciated.
Also, if you see anything else that could be done better, please comment and explain. Thanks!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ShutdownPC
{
public partial class Form1 : Form
{
int inputHours;
int inputMinutes;
int inputSeconds;
Thread sleepingThread;
Thread updatingThread;
NotifyIcon shutdownPCIcon;
Icon defaultIcon;
public Form1()
{
InitializeComponent();
defaultIcon = new Icon("defaultIcon.ico");
shutdownPCIcon = new NotifyIcon();
shutdownPCIcon.Icon = defaultIcon;
shutdownPCIcon.Visible = true;
MenuItem progNameMenuItem = new MenuItem("ShutdownPC by Conor");
MenuItem breakMenuItem = new MenuItem("-");
MenuItem quitMenuItem = new MenuItem("Quit");
ContextMenu contextMenu = new ContextMenu();
contextMenu.MenuItems.Add(progNameMenuItem);
contextMenu.MenuItems.Add(breakMenuItem);
contextMenu.MenuItems.Add(quitMenuItem);
shutdownPCIcon.ContextMenu = contextMenu;
shutdownPCIcon.Text = "ShutdownPC";
quitMenuItem.Click += QuitMenuItem_Click;
}
private void QuitMenuItem_Click(object sender, EventArgs e)
{
shutdownPCIcon.Dispose();
sleepingThread.Abort();
updatingThread.Abort();
this.Close();
}
public void sleepThread()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(sleepThread));
}
else {
textBox1.Enabled = false;
textBox2.Enabled = false;
textBox3.Enabled = false;
button1.Enabled = false;
int totalMilliseconds = ((inputHours * 3600) + (inputMinutes * 60) + inputSeconds) * 1000;
Thread.Sleep(totalMilliseconds);
//Process.Start("shutdown", "/s /t 0");
richTextBox1.AppendText(String.Format("test"));
}
}
public void updateThread()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(updateThread));
}
else {
int totalSeconds = (inputHours * 3600) + (inputMinutes * 60) + inputSeconds;
while (totalSeconds > 0)
{
TimeSpan time = TimeSpan.FromSeconds(totalSeconds);
string timeOutput = time.ToString(#"hh\:mm\:ss");
richTextBox1.AppendText(String.Format(timeOutput));
Thread.Sleep(1000);
richTextBox1.Clear();
totalSeconds--;
}
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
inputHours = Convert.ToInt32(textBox1.Text);
inputHours = int.Parse(textBox1.Text);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
inputMinutes = Convert.ToInt32(textBox2.Text);
inputMinutes = int.Parse(textBox2.Text);
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
inputSeconds = Convert.ToInt32(textBox3.Text);
inputSeconds = int.Parse(textBox3.Text);
}
private void button1_Click(object sender, EventArgs e)
{
updatingThread = new Thread(new ThreadStart(updateThread));
updatingThread.Start();
sleepingThread = new Thread(new ThreadStart(sleepThread));
sleepingThread.Start();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
}
}

Using Invoke in the beginning of method that runs in separate thread is bad idea, because all code runs in GUI thread and lock it.
You should Invoke only GUI updating code!!!

Related

How to change label text and color when a condition is met? (C#)

I am making a password generator and on websites when you enter certain conditions are met the strength of the password changes how can I change the color and text of the label when the password strength is >= 8, <8<10, >12?
Here is the Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Password_Generator
{
public partial class PassGen : Form
{
int currentPasswordLength = 0;
Random Character = new Random();
private void PasswordGenerator(int PasswordLength)
{
String validChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$&?";
String randomPassword = "";
//25
for(int i = 0; i < PasswordLength; i++)
{
int randomNum = Character.Next(0, validChars.Length);
randomPassword += validChars[randomNum];
}
Password.Text = randomPassword;
}
public PassGen()
{
InitializeComponent();
PasswordLengthSlider.Minimum = 5;
PasswordLengthSlider.Maximum = 22;
PasswordGenerator(5);
}
private void Label1_Click(object sender, EventArgs e)
{
}
private void Copy_Click(object sender, EventArgs e)
{
Clipboard.SetText(Password.Text);
}
//52
private void PasswordLength_Click(object sender, EventArgs e)
{
}
private void PasswordLengthSlider_Scroll(object sender, EventArgs e)
{
PasswordLength.Text = "Password Length:" + " " + PasswordLengthSlider.Value.ToString();
currentPasswordLength = PasswordLengthSlider.Value;
PasswordGenerator(currentPasswordLength);
}
private void pswdStrengthTest()
{
if (currentPasswordLength <= 8)
{
pswdStrength.Text = "weak";
pswdStrength.ForeColor = Color.Red;
} else if (currentPasswordLength<= 9)
{
pswdStrength.Text = "ok";
pswdStrength.ForeColor = Color.Blue;
}
}
//78
private void pswdStrength_Click(object sender, EventArgs e)
{
}
}
}
If anyone could help me with this it would be greatly appreciated. This is based off a tutorial I found on YouTube. I'm not sure what the video is called but if it helps I could search for it and update my posting.
Try this:
Password.TextChanged += (s1, e1) =>
{
if (Password.Text.Length > 10)
pswdStrength.ForeColor = Color.Green
else if (Password.Text.Length > 8)
pswdStrength.ForeColor = Color.Blue
else
pswdStrength.ForeColor = Color.Red
};
Your code looks like a windows form application.
If you have for example one objetc txt_password, check to code some of these events:
TextChanged: this occurs when your textbox has been changed
Others events could be:
KeyPress or KeyDown

C# Aforge MJPEG stream motiondetection

I am still new at programming, I code as a hobby :)
I wanted to make a MJPEG streaming aplication with an option to record a video and save it on computer when it detects a moving. So far i've managed to get stream to videosourceplayer in WPF, but it seems that i can't manage to get the information whether moving is detected or not. What am i doing wrong? i've tried many things ( commented ). but it seems that i can't compare float MotionDetected to limited (in my case 0.02). my label5 simply doesnt change.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge.Vision.Motion;
using AForge.Video;
using AForge.Video.DirectShow;
using Accord.Video.FFMPEG;
using System.Globalization;
using AForge.Controls;
namespace AnotherAForge
{
public partial class Form1 : Form
{
MotionDetector Detector;
float f;
float MotionDetected;
int frames;
private VideoFileWriter _writer;
private MJPEGStream stream = new MJPEGStream("link to the cam i can't share");
int uporabimotiondetection = 0;
private IVideoSource _videoSource;
public Form1()
{
InitializeComponent();
}
Form form1 = new Form();
public void videoSourcePlayer1_NewFrame(object sender, ref Bitmap image)
{
if (uporabimotiondetection == 1)
{
MotionDetected = Detector.ProcessFrame(image);
//if (label5.InvokeRequired) {
// label5.Text = NivelDeDeteccion.ToString();
//}
//if (Detector.ProcessFrame(image) > 0.02)
//{
// label5.Text = "1";
//}
}
frames++;
}
private void alarm() {
label2.Text = MotionDetected.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
//VideoStream.NewFrame += VideoStream_NewFrame;
//VideoStream.NewFrame += new NewFrameEventHandler(ProcessNewFrame);
stream.Start();
//stream.NewFrame += Stream_NewFrame;
//videoSourcePlayer1.NewFrame += videoSourcePlayer1_NewFrame;
videoSourcePlayer1.VideoSource = stream;
timer1.Enabled = true;
timer1.Start();
timer2.Start();
//pictureBox1.Image = image;
GC.Collect();
}
private void Form1_Load(object sender, EventArgs e)
{
Detector = new MotionDetector(new TwoFramesDifferenceDetector(),new MotionAreaHighlighting());
MotionDetected = 0;
}
private void timer1_Tick(object sender, EventArgs e)
{
// textBox1.Text = NivelDeDeteccion.ToString();
label3.Text = frames.ToString() + " frames";
label2.Text = MotionDetected.ToString();
if (MotionDetected <= 0.02 && MotionDetected >= 0)
{
label5.Text = "1";
}
else {
label5.Text = "0";
}
}
private void button2_Click(object sender, EventArgs e)
{
Console.Beep();
}
int time;
private void timer2_Tick(object sender, EventArgs e)
{
time++;
label4.Text = time.ToString();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
stream.Stop();
}
private void button3_Click(object sender, EventArgs e)
{
stream.Stop();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked == true)
{
uporabimotiondetection = 1;
}
else {
uporabimotiondetection = 0;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
//textBox1.Text = string.Format("{0:0.00000}", textBox1.Text);
//float motionlevel = float.Parse(MotionDetected);
//float a = 1;
//textBox2.Text = a.ToString();
//float b = MotionDetected / 100;
//textBox1.Text = b.ToString();
//double limiter = Convert.ToDouble("0,02");
//textBox2.Text = limiter.ToString();
//if (MotionDetected < (0.02f / 1000))
//{
// label5.Text = "gibanje";
//}
//else
//{
// label5.Text = "ni gibanja!";
//}
}
}
}

Caller ID Check if Caller has ended Call

I have a program that gets the incoming number, date and time. I want to check however if the person who is ringing me has put the phone down, how can I do this?
Below is the code which I currently have:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace CallerID
{
public partial class CallerID : Form
{
int timesTicked = 0;
Point defaultLocation = new Point();
Point newLocation = new Point();
public CallerID()
{
InitializeComponent();
port.Open();
SetModem(); // SetModem(); originally went after WatchModem();
WatchModem();
//SetModem();
telephoneTimer.Interval = 16;
telephoneTimer.Tick += new EventHandler(telephoneTimer_Tick);
defaultLocation = pictureBox1.Location;
newLocation = pictureBox1.Location;
}
void telephoneTimer_Tick(object sender, EventArgs e)
{
if (timesTicked <= 2)
newLocation.X++;
if (timesTicked >= 4)
newLocation.X--;
if (timesTicked == 6)
{
timesTicked = 0;
pictureBox1.Location = defaultLocation;
newLocation = defaultLocation;
}
pictureBox1.Location = newLocation;
timesTicked++;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
WatchModem();
}
private SerialPort port = new SerialPort("COM3");
string CallName;
string CallNumber;
string ReadData;
private void SetModem()
{
port.WriteLine("AT+VCID=1\n");
//port.WriteLine("AT+VCID=1");
port.RtsEnable = true;
}
private void WatchModem()
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
public delegate void SetCallerIdText();
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
ReadData = port.ReadExisting();
//Add code to split up/decode the incoming data
//if (lblCallerIDTitle.InvokeRequired)
if (ReadData.Contains("NMBR"))
{
lblData.Invoke(new SetCallerIdText(() => lblData.Text = ReadData));
}
//else
// lblCallerIDTitle.Text = ReadData;
}
private void lblData_TextChanged(object sender, EventArgs e)
{
telephoneTimer.Start();
button1.Visible = true;
}
}
}
Please ignore the Timer Code as that is just for animation.
Have you tried the PinChanged event? Normally Carrier Detect will go low when the remote end disconnects.

Passing argument into backgroundWorker (for use as a Cancel button)

I'm new to C# and object-oriented programming in general. I've been trying to implement a "Cancel" button into my GUI so that the user can stop it mid-process.
I read this question: How to implement a Stop/Cancel button? and determined that a backgroundWorker should be a good option for me, but the example given doesn't explain how to hand arguments to the backgroundWorker.
My problem is that I do not know how to pass an argument into backgroundWorker such that it will stop the process; I have only been able to get backgroundWorker to stop itself.
I created the following code to try to learn this, where my form has two buttons (buttonStart and buttonStop) and a backgroundWorker (backgroundWorkerStopCheck):
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
using System.Timers;
namespace TestBackgroundWorker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Set the background worker to allow the user to stop the process.
backgroundWorkerStopCheck.WorkerSupportsCancellation = true;
}
private System.Timers.Timer myTimer;
private void backgroundWorkerStopCheck_DoWork(object sender, DoWorkEventArgs e)
{
//If cancellation is pending, cancel work.
if (backgroundWorkerStopCheck.CancellationPending)
{
e.Cancel = true;
return;
}
}
private void buttonStart_Click(object sender, EventArgs e)
{
// Notify the backgroundWorker that the process is starting.
backgroundWorkerStopCheck.RunWorkerAsync();
LaunchCode();
}
private void buttonStop_Click(object sender, EventArgs e)
{
// Tell the backgroundWorker to stop process.
backgroundWorkerStopCheck.CancelAsync();
}
private void LaunchCode()
{
buttonStart.Enabled = false; // Disable the start button to show that the process is ongoing.
myTimer = new System.Timers.Timer(5000); // Waste five seconds.
myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
myTimer.Enabled = true; // Start the timer.
}
void myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
buttonStart.Enabled = true; // ReEnable the Start button to show that the process either finished or was cancelled.
}
}
}
The code, if it worked properly, would just sit there for five seconds after the user clicked "Start" before re-enabling the Start button, or would quickly reactivate the Start button if the user clicked "Stop".
There are two problems with this code that I am not sure how to handle:
1) The "myTimer_Elapsed" method results in an InvalidOperationException when it attempts to enable the Start button, because the "cross-thread operation was not valid". How do I avoid cross-thread operations?
2) Right now the backgroundWorker doesn't accomplish anything because I don't know how to feed arguments to it such that, when it is canceled, it will stop the timer.
I'd appreciate any assistance!
First of all, the problem to avoid "cross-thread operation was not valid" is use Invoke on controls. You cannot use a control from a different thread.
About the second issue, I would implement it in the following way. This is a minimum background worker implementation with cancel support.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Set the background worker to allow the user to stop the process.
backgroundWorkerStopCheck.WorkerSupportsCancellation = true;
backgroundWorkerStopCheck.DoWork += new DoWorkEventHandler(backgroundWorkerStopCheck_DoWork);
}
private void backgroundWorkerStopCheck_DoWork(object sender, DoWorkEventArgs e)
{
try
{
for (int i = 0; i < 50; i++)
{
if (backgroundWorkerStopCheck.CancellationPending)
{
// user cancel request
e.Cancel = true;
return;
}
System.Threading.Thread.Sleep(100);
}
}
finally
{
InvokeEnableStartButton();
}
}
private void buttonStart_Click(object sender, EventArgs e)
{
//disable start button before launch work
buttonStart.Enabled = false;
// start worker
backgroundWorkerStopCheck.RunWorkerAsync();
}
private void buttonStop_Click(object sender, EventArgs e)
{
// Tell the backgroundWorker to stop process.
backgroundWorkerStopCheck.CancelAsync();
}
private void InvokeEnableStartButton()
{
// this method is called from a thread,
// we need to Invoke to avoid "cross thread exception"
if (this.InvokeRequired)
{
this.Invoke(new EnableStartButtonDelegate(EnableStartButton));
}
else
{
EnableStartButton();
}
}
private void EnableStartButton()
{
buttonStart.Enabled = true;
}
}
internal delegate void EnableStartButtonDelegate();
}
About passing arguments to the worker, you can pass any object in the RunWorkerAsync() method, and its reveived in the backgroundWorkerStopCheck_DoWork method:
...
backgroundWorkerStopCheck.RunWorkerAsync("hello");
...
private void backgroundWorkerStopCheck_DoWork(object sender, DoWorkEventArgs e)
{
string argument = e.Argument as string;
// argument value is "hello"
...
}
Hope it helps.
try this example and you will see how to pass data to and from the BackgroundWorker:
public partial class Form1 : Form
{
BackgroundWorker bw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.WorkerSupportsCancellation = true;
}
private void button1_Click(object sender, EventArgs e)
{
btnStart.Enabled = false;
btnCancel.Enabled = true;
double[] data = new double[1000000];
Random r = new Random();
for (int i = 0; i < data.Length; i++)
data[i] = r.NextDouble();
bw.RunWorkerAsync(data);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnStart.Enabled = true;
btnCancel.Enabled = false;
if (!e.Cancelled)
{
double result = (double)e.Result;
MessageBox.Show(result.ToString());
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
double[] data = (double[])e.Argument;
for (int j = 0; j < 200; j++)
{
double result = 0;
for (int i = 0; i < data.Length; i++)
{
if (bw.CancellationPending)
{
e.Cancel = true;
return;
}
result += data[i];
}
e.Result = result;
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
bw.CancelAsync();
btnStart.Enabled = true;
btnCancel.Enabled = false;
}
}

Backgroundworker not Rendering Window fluently

I just got into WPF and am currently trying my luck with the Background worker, so I figured I'd just open any file using the FileOpenDialog, loop through all the bytes inside the file and report the total progress via worker.ReportProgress in percentage ... alas, this only works for like ~20 times and then it gets really stuck and suddenly stops at 100%.
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;
using System.Threading;
using System.ComponentModel;
namespace BitStream
{
public partial class MainWindow : Window
{
private int bytes = 0;
private long length = 0;
public MainWindow()
{
InitializeComponent();
}
private void selectFile_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
OpenFileDialog ofd = new OpenFileDialog();
if ((bool)ofd.ShowDialog())
{
FileInfo fi = new FileInfo(ofd.FileName);
this.length = fi.Length;
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.ProgressChanged += bw_ProgressChanged;
bw.WorkerReportsProgress = true;
Stream str = ofd.OpenFile();
bw.RunWorkerAsync(str);
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
Stream str = (Stream)e.Argument;
int singleByte = 0;
this.Dispatcher.Invoke(
new Action(() =>
{
int currentProgress = 0;
while ((singleByte = str.ReadByte()) != -1)
{
label1.Content = singleByte;
bytes++;
currentProgress = Convert.ToInt32(((double)bytes) / length * 100);
if (currentProgress > progress)
{
progress = currentProgress;
((BackgroundWorker)sender).ReportProgress(progress);
Thread.Sleep(100);
}
}
}
), System.Windows.Threading.DispatcherPriority.Render);
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label2.Content = e.ProgressPercentage + "% completed";
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
Labels 1 and 2 are there for showing the current byte and the current progress in %.
Feel free to also criticize every other aspect of my code, I just got started with WPF today.
Edited DoWork-Method:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
Stream str = (Stream)e.Argument;
int singleByte = 0;
int currentProgress = 0;
while ((singleByte = str.ReadByte()) != -1)
{
this.Dispatcher.Invoke(
new Action(() =>
{
label1.Content = singleByte;
}), System.Windows.Threading.DispatcherPriority.Render);
bytes++;
currentProgress = Convert.ToInt32(((double)bytes) / length * 100);
if (currentProgress > progress)
{
progress = currentProgress;
this.Dispatcher.Invoke(
new Action(() =>
{
((BackgroundWorker)sender).ReportProgress(progress);
}), System.Windows.Threading.DispatcherPriority.Render);
Thread.Sleep(500);
}
}
}
Thanks,
Dennis
So assuming you really want to make a cross thread call for each byte (which I wouldn't recommend), the code would look something like:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
Stream str = (Stream)e.Argument;
int singleByte = 0;
int currentProgress = 0;
while ((singleByte = str.ReadByte()) != -1)
{
bytes++;
this.Dispatcher.Invoke(
new Action(() =>
{
label1.Content = singleByte;
}
), System.Windows.Threading.DispatcherPriority.Render);
currentProgress = Convert.ToInt32(((double)bytes) / length * 100);
if (currentProgress > progress)
{
progress = currentProgress;
((BackgroundWorker)sender).ReportProgress(progress);
Thread.Sleep(100);
}
}
}
The idea being that you can only manipulate a DispatcherObject on the thread on which it was created.
First thought is you aren't disposing the return from the openfiledialog so the more times you run it the more resources you throw away...
I would have thrown the filename at the worker and then let it manage the resource, but
using(Stream s = ofd.OpenFileDalog())
{
get length and such
}
// run up woker pass filename.
in your calling code will solve the problem, as I'm assuming you are using length to sort out your progress bar.

Categories