Thread isn't Starting - c#

I'm new to c# and Multithreading. I have this code to getting started with Multithreading but clock tick isn't getting started. What's wrong with this code? No error occurs because its a logical error I guess. Any help would be appreciated.
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 System.Threading;
namespace Implementing_Databases
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
picturebox1.Location=new Point(0,20);
pictureBox2.Location = new Point(0, 60);
}
int B1 = 0;
int B2 = 0;
private void Form1_Load(object sender, EventArgs e)
{
Thread Th1 = new Thread(Go1);
Thread Th2 = new Thread(Go2);
Th1.Start();
Th2.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
picturebox1.Left = B1;
B1 += 5;
}
private void timer2_Tick(object sender, EventArgs e)
{
pictureBox2.Left = B2;
B2 += 5;
}
void Go1()
{
timer1.Start();
}
void Go2()
{
timer2.Start();
}
}
}

First of all, try declaring threads as properties of form rather than declaring them as local function variables. Because otherwise they may be collected by GC straight away after Load handler exits.
Secondly, UI not updating may be due to the fact that you cannot update UI data from non GUI thread. See InvokeRequired/Invoke feature of WinForms programming. See https://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired(v=vs.110).aspx for more details

Related

Fade out exit requires 2 clicks instead of one

I'm trying to implement a fade in/out to main form open/close, open fade in works fine, however close fade out requires 2 button clicks to work.
Current 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;
using System.IO;
using System.Diagnostics;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace DEMO
{
public partial class MainForm : Form
// fade in timer set
System.Windows.Forms.Timer t1 = new System.Windows.Forms.Timer();
System.Windows.Forms.Timer t2 = new System.Windows.Forms.Timer();
private void Form_Load(object sender, EventArgs e)
{
//fade in function
Opacity = 0;
t1.Interval = 10;
t1.Tick += new EventHandler(fadeIn);
t1.Start();
}
// fade in
void fadeIn(object sender, EventArgs e)
{
if (Opacity >= 1)
t1.Stop();
else
Opacity += 0.05;
}
// fade out
void fadeOut(object sender, EventArgs e)
{
if (Opacity <= 0)
{
t2.Stop();
Close();
}
else
Opacity -= 0.15;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
e.Cancel = true;
t2.Tick += new EventHandler(fadeOut);
t2.Start();
if (Opacity <= 0)
e.Cancel = false;
}
private void customImageButton1_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
I first tried to make it like the button to do the tick start with the e.Cancel but changing the EventArgs e to FormClosingEventArgs e only gave the error: No overload for 'customImageButton1_Click' matches delegate 'System.EventHandler' on which I couldn't find a solution

How to update an Readonly textbox constantly C#

I am wondering how to constantly update an readonly textbox.
The text box displays a text that always changes.
My problem is if I create an loop the application won't start and if I start the loop using a button my application freezes and only it only runs the loop.
I also can't use a new thread or the thread that I use to change the variables that are displayed within the text because in this case I just get an error System.InvalidOperationException
I was searching for anwser but I couldn't find one.
When using a thread you have to cause your ui update work to run on the UI thread, and that's where you use an "invoke".
There are many ways to achieve your goal, I'll show you two ways you can do it:
using a thread (BackgroundWorker is just a fancier way to do that)
a Timer (it might be overkill to use a thread just to update a
counter if that is what you are intending).
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 WindowsFormsApp2
{
public partial class Form1 : Form
{
bool m_shutdown = false;
int m_counter = 0;
Timer m_timer = new Timer();
BackgroundWorker m_backgroundworker = new BackgroundWorker();
bool m_usetimerway = false; // change this to true to try the timer way
Action m_actionupdatecounter;
public Form1()
{
InitializeComponent();
m_actionupdatecounter = new Action(() =>
{
UpdateCounter();
});
}
private void Form1_Load(object sender, EventArgs e)
{
if (m_usetimerway)
{
m_timer.Interval = 50;
m_timer.Tick += M_timer_Tick;
m_timer.Enabled = true;
}
else
{
m_backgroundworker.DoWork += M_backgroundworker_DoWork;
m_backgroundworker.RunWorkerCompleted += M_backgroundworker_RunWorkerCompleted;
m_backgroundworker.RunWorkerAsync();
}
}
void UpdateCounter()
{
if (this.InvokeRequired)
{
// Get it to be run on the UI thread
this.BeginInvoke( m_actionupdatecounter );
}
else
{
m_counter++;
textBoxCounter.Text = string.Format("{0}", m_counter);
}
}
private void M_timer_Tick(object sender, EventArgs e)
{
// This is already on the UI thread because it's a "WinForms" timer
UpdateCounter();
}
private void M_backgroundworker_DoWork(object sender, DoWorkEventArgs e)
{
while (!m_shutdown)
{
UpdateCounter();
System.Threading.Thread.Sleep(50);
}
}
private void M_backgroundworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
m_shutdown = true;
// To have a more graceful shutdown, you might want to wait for the
// background worker to have "completed" before you actually exit
// your winforms app.
}
}
}

cannot get progressbar animation with code, progresschanged not called

i'm trying to do the code here
http://www.dotnetperls.com/progressbar
Here is the code I have. I've drawn on a backgroundworker, and programmatically added a progress bar.
I've tried stepping over the code, and i've tried using messageboxes to see what is going on, and it looks like it is only executing one iteration of the for loop, which is for when i=0, and it seems it goes from that, to te done procedure, and the Progress procedure never gets invoked.
And the progress bar never changes value from 0.
When I want it to progress to 100.
I did try commenting out this line //Application.EnableVisualStyles(); in program.cs to remove a natural animation that the progerss bar has, but either way, commented or uncommented, jt's not even running every iteration of the for loop, it's quitting after i=0.. And there is no progress with the backgroundworker, or the progress bar.
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 System.Threading;
namespace backgroundworker2
{
public partial class Form1 : Form
{
ProgressBar progressBar1 = new ProgressBar();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// progressBar1.BackColor = Color.Red;
this.Controls.Add(progressBar1);
//progressBar1.Value = 100;
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// textBox1.Text = "0";
for (int i = 0; i < 100; i++)
{
// MessageBox.Show("a"+i);
Thread.Sleep(1000);
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("done");
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// textBox1.Text = Convert.ToString( e.ProgressPercentage);
progressBar1.Value = e.ProgressPercentage;
// MessageBox.Show("asdf");
}
}
}
In Form1_Load you run the BackgroundWorker but you haven't set it's WorkerReportsProgress property to true. The default is false. So you need to add this line before you call the RunWorkerAsync() method:
backgroundWorker1.WorkerReportsProgress = true;

C# FORM with image and auto close

I have a problem I made a new form, with background img, and all I need and its working like I wanted, but I also need to auto close it after 5 or 10 seconds.
I searched on google all day ... but no tutorial was good.
I use Visual Studio 2013.
Can you boys help me please...
I'm desperate right now... its almost 10 hours since I'm trying.
You are my last hope.
Thanks
this.close() dosen't did it, or I made it wrong but i doubt that.
Application.Exit fail
timers give errors...
//form
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 Cerum_HS
{
public partial class CERUM_HS : Form
{
public CERUM_HS()
{
InitializeComponent();
Rectangle r = Screen.PrimaryScreen.WorkingArea;
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - this.Width, Screen.PrimaryScreen.WorkingArea.Height - this.Height);
}
}
}
//main.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
//using System.Windows.Forms;
namespace Cerum_HS
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
private static System.Timers.Timer aTimer;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CERUM_HS());
aTimer = new System.Timers.Timer();
aTimer.Interval = 10;
aTimer = new System.Timers.Timer(10);
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = false;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
//Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
Application.Exit();
//this.close();
}
}
}
Since my comment seemed to help, I thought I write it down as an answer.
public partial class CERUM_HS :
{
// here is the timer for the automatic closing
private static System.Timers.Timer aTimer;
public CERUM_HS()
{
InitializeComponent();
Rectangle r = Screen.PrimaryScreen.WorkingArea;
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - this.Width, Screen.PrimaryScreen.WorkingArea.Height - this.Height);
}
private void Form_Load(object sender, System.EventArgs e)
{
// start here the timer when the form is loaded
aTimer = new System.Timers.Timer();
aTimer.Interval = 10;
aTimer = new System.Timers.Timer(10);
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = false;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
// Close the Application when this event is fired
Application.Exit();
}
}
Bogdan please comment if this implementation is how it worked for you in the end.
I would put a PictureBox and timer on your form (set to 5000 ms), click on the Tick event, and use this code:
namespace Image
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// set picture box to image of interest
// size and position form appropriately
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
this.Close();
}
}
}

Application is not responding

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!!!

Categories