I have some timers that are updating a DataSet. I need the timers to run sequentially without bumping into each one after the other. I might be running only one or two or three at the same time. So the idea is they have to run 1,2,3 and then again 1,2,3. I created this fiddle but I don't have it down yet:
class Example
{
private static ManualResetEvent mr = new ManualResetEvent(false);
private static AutoResetEvent event_1 = new AutoResetEvent(true);
private static AutoResetEvent event_2 = new AutoResetEvent(false);
private static void t1_Tick(object sender, EventArgs e)
{
//update ds inside here
//ds.Tables["Alarms"].Rows[0][0]="foo";
//same in all other Tick functions
Console.WriteLine("1");
mr.Set();
}
private static void t2_Tick(object sender, EventArgs e)
{
mr.WaitOne();
Console.WriteLine("2");
mr.Set();
}
private static void t3_Tick(object sender, EventArgs e)
{
mr.WaitOne();
Console.WriteLine("3");
mr.Set();
}
static void Main()
{
System.Timers.Timer t1 = new System.Timers.Timer();
t1.Elapsed += t1_Tick;
t1.Enabled = true;
System.Timers.Timer t2 = new System.Timers.Timer();
t2.Elapsed += t2_Tick;
t2.Enabled = true;
System.Timers.Timer t3 = new System.Timers.Timer();
t1.Elapsed += t1_Tick;
t1.Enabled = true;
Console.ReadKey();
}
}
If there are only two timers running it would have to be 1,2 an then again 1,2
Could you use a thread-safe DispatcherTimer instead?
See http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx
Related
I am trying automatic write data to textbox9. I am using timer, but I don't find why it's not working. Maybe somebody have suggest for me.
System.Timers.Timer aTimer;
public int i;
private void Form1_Load(object sender, EventArgs e)
{
i = 0;
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimeEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
public void OnTimeEvent(object source, System.Timers.ElapsedEventArgs e)
{
i = i + 1;
textBox9.Text = i.ToString();
}
First, you need to move the "aTimer" and the "i" variables outside the methods at declare them at the form level. In the code you provided, those variables are not declared anywhere.
Second, the System.Timers.Timer will run outside the main thread, and it is not safe to access a control (textbox) from its events. So, you need to use the System.Windows.Forms.Timer, like so:
private System.Windows.Forms.Timer aTimer;
private int i = 0;
private void Form1_Load(object sender, EventArgs e)
{
i = 0;
aTimer = new System.Windows.Forms.Timer();
aTimer.Tick += ATimer_Tick;
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
private void ATimer_Tick(object sender, EventArgs e)
{
i = i + 1;
textBox9.Text = i.ToString();
}
System.Timers.Timer by default calls its Elapsed in thread from a pool, different from main and attempt to change UI control from that thread should fire an exception.
You need to assign it SynchronizingObject:
aTimer.SynchronizingObject = this; // this = form
Or use System.Windows.Forms.Timer which is timer component designed for UI.
In my program I need to generate an instance of a class which is "Vehicle", the Vehicle class has a timer within it, along with a boolean "vExists", when the timer hits an interval.
class VehicalGen
{
private Random rn1 = new Random();
private int agrotime;
private bool vExists;
//static AgrivationHandler agroTimeHandler;
private static Timer agroTimer = new Timer(100);
//agrotime: anywhere between 2 and 4 seconds (2000 to 4000)
///Generates the new Vehicles using GetCarType to change the outcome of the later variables
public VehicalGen()
{
this.vtype = RandomGeneration.GetCarType(rn1);
switch (this.vtype)
{
[....] //This is where the details of the vehicle are generated.
}
this.agrotime = RandomGeneration.GetRandomTime224(rn1);
this.vExists = true;
this.serviced = false;
//agroTimeHandler = new AgrivationHandler(agrotime);
agroTimer.Interval = agrotime;
agroTimer.Elapsed += AgroTimerElapsed;
agroTimer.Start();
}
public static void AgroTimerElapsed(object sender, ElapsedEventArgs e)
{
//here is where I need to set vExists to "False"
}
}
However I need to generate a specific instance of the class as far as I'm aware to do that, because it doesn't like "this.vExists = false", it just errors.
Yes is possible.
Try the following:
private void LoadTimer()
Timer timer = new Timer
timer.Interval = 4000;
timer.Enabled = true;
timer.Tick += new EventHandler(timer1_Tick);
timer.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
// do your boolean operation where
}
basically I'm trying to implement the timer in class for my would-be very first game in C#; I want to use timers that will constantly update the player and provide certain periodic feedback, but I can't seem to get the 'timer' class to work correctly. If I use it in a loop (as shown below), it will wait 2 seconds, and then keep writing "You're Alive!" to the console with 0 delay in-between; and if I do not use the loop, the application just ends instantly.
using System;
using System.Timers;
public class MyClass
{
public static void myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("You're alive!");
}
public static void Main(String[] args)
{
while (true)
{
Timer MyTimer = new Timer();
MyTimer.Interval = 2000;
MyTimer.Enabled = true;
MyTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
MyTimer.Start();
}
}
Just add below line after MyTimer.Start();
Console.ReadLine();
static void Main(String[] args)
{
Timer MyTimer = new Timer();
MyTimer.Interval = 2000;
MyTimer.Enabled = true;
MyTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
MyTimer.Start();
Console.ReadLine();
}
private static void myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("You're alive!");
}
I need to freeze the main thread until the end recursion.
Recursion depth = count of threads.
sample code:
BackgroundWorker backgroundWorker1;
Random ran;
private void Form1_Load(object sender, EventArgs e)
{
method();
label1.Text = "Threads is finished";
}
private void method() // recursive method
{
Thread.Sleep(100);
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork +=
new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerAsync(); //Beginning new thread
}
private void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e)
{
ran = new Random();
Thread.Sleep(ran.Next(500, 1000));
if (ran.Next(1, 5) != 1) // if = 1 then to stop recursion
{
method();
}
}
When the threads are completed, label1.Text must have the value "Threads is finished". How is this done?
Console application PoC which caches references to all created workers and uses numeric variable to check how many workers still in progress, when this value reaches 0 - application terminates. Please let me know in case of any questions.
class Program
{
private static IList<BackgroundWorker> workers;
private static Random ran;
private static int activeWorkersCount;
static void Main(string[] args)
{
workers = new List<BackgroundWorker>();
DoWork();
while (activeWorkersCount > 0)
{
Thread.Sleep(200);
}
Console.WriteLine("Waiting for all workers to finish...");
Console.ReadLine();
}
private static void DoWork() // recursive method
{
Thread.Sleep(100);
var newWorker = new BackgroundWorker();
newWorker.DoWork += BackgroundWorkerDoWork;
newWorker.RunWorkerCompleted += (o, e) =>
{
Console.WriteLine("[E] Worker finished");
Interlocked.Decrement(ref activeWorkersCount);
};
Interlocked.Increment(ref activeWorkersCount);
newWorker.RunWorkerAsync();
}
private static void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("[S] Worker started");
ran = new Random();
Thread.Sleep(ran.Next(500, 1000));
if (ran.Next(1, 5) != 1) // if = 1 then to stop recursion
{
DoWork();
}
}
}
When you decide it's time to stop recursion you can post a callback onto the GUI thread. Off the top of my head it'll be something like this:
if(ran.Next(1,5)!=1)
{
method();
}
else
{
Action action=()=>label1.Text = "Threads is finished";
this.BeginInvoke(action);
}
1) Create a method to update Label1:
private void WorkFinished()
{
if(Label1.InvokeRequired)
{
Label1.Invoke(WorkFinished);
}
else
{
Label1.Text = "Threads is finished";
}
}
2) Call WorkFinished() from backgroundWorker1_DoWork.
You can use CountDownEvent class:
Example:
using (CountDownEvent countdownEvent = new CountdownEvent(numberOfThreads))
{
for (int threadIndex= 0; i < numberOfThreads; threadIndex++)
ThreadPool.QueueUserWorkItem(
th =>
{
DoWork();
countdownEvent.Signal();
}, threadIndex);
countdownEvent.Wait();
}
Console.WriteLine("All threads complete");
I did it using a volatile integer number and it works well.
BackgroundWorker backgroundWorker1;
Random ran;
long runningThreads = 0;
public void Start()
{
method();
// Console.WriteLine("Threads is finished");
}
private void method() // recursive method
{
Interlocked.Increment(ref runningThreads);
Console.WriteLine("New thread started");
Thread.Sleep(100);
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork +=
new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerAsync(); //Beginning new thread
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ran = new Random();
Thread.Sleep(ran.Next(500, 1000));
if (ran.Next(1, 5) != 1) // if = 1 then to stop recursion
{
method();
}
Finished();
}
private void Finished()
{
Interlocked.Decrement(ref runningThreads);
if (Interlocked.Read(ref runningThreads) == 0)
{
Console.WriteLine("Threads is finished");
}
}
I have four buttons that are called "ship1,ship2" etc.
I want them to move to the right side of the form (at the same speed and starting at the same time), and every time I click in one "ship", all the ships should stop.
I know that I need to use a timer (I have the code written that uses threading, but it gives me troubles when stopping the ships.) I don't know how to use timers.
I tried to read the timer info in MDSN but I didn't understand it.
So u can help me?
HERES the code using threading.
I don't want to use it. I need to use a TIMER! (I posted it here because it doesnt give me to post without any code
private bool flag = false;
Thread thr;
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
flag = false;
thr = new Thread(Go);
thr.Start();
}
private delegate void moveBd(Button btn);
void moveButton(Button btn)
{
int x = btn.Location.X;
int y = btn.Location.Y;
btn.Location = new Point(x + 1, y);
}
private void Go()
{
while (((ship1.Location.X + ship1.Size.Width) < this.Size.Width)&&(flag==false))
{
Invoke(new moveBd(moveButton), ship1);
Thread.Sleep(10);
}
MessageBox.Show("U LOOSE");
}
private void button1_Click(object sender, EventArgs e)
{
flag = true;
}
Have you googled Windows.Forms.Timer?
You can start a timer via:
Timer timer = new Timer();
timer.Interval = 1000; //one second
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.Start();
You'll need an event handler to handle the Elapsed event which is where you'll put the code to handle moving the 'Button':
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MoveButton();
}