I'm currently using a stopwatch as a global timer. I have main thread running, another thread, and an event method.
The main thread launches the other thread and the event method is triggered by events. Both methods will call the stopwatch and get its time. The thing is, the times are not consistent:
from main thread:
START REC AT 9282
STOp REC AT 19290
from another thread:
audio 1
audio 304
audio 354
audio 404
audio 444
audio 494
audio 544
audio 594
from event method:
video 4
video 5
video 29
video 61
video 97
video 129
video 161
I don't get why if i start my rec at 9282, the other two functions that call the stopwatch will have timers that start at zero? Is this a thread related issue? How can i fix this? Thanks
UPDATE:*********
when i save my frames i changed to:
long a = relogio.EllapseMilliseconds
i print out this value and its ok, as expected. but when i print the value stored in the lists, they come as starting from the beggining. strange huh?
SORRY FOR ALL THE TROUBLE, I PRINTED IT WITHOUT THE STARTING TIME,THATS WHY THEY ALL SEEMED TO START FROM ZERO! MANY THANKS AND SORRY!
main thread
private void Start_Recording_Click(object sender, RoutedEventArgs e)
{
rec_starting_time = relogio.ElapsedMilliseconds;
Console.WriteLine("START REC AT " + rec_starting_time);
write_stream.enableRecording();
Thread a = new Thread(scheduleAudioVideoFramePicks);
a.Start();
scheduleAudioVideoFramePicks - this thread just counts the time, so i know when to stop
//while....
if (rec_starting_time + time_Actual > rec_starting_time+recording_time * 1000)//1000 - 1s = 1000ms
{
totalRecordingTimeElapsed = true;
write_stream.disableRecording();
Console.WriteLine("STOp REC AT " + relogio.ElapsedMilliseconds);
}
//end while
lock (list_audio)
{
int b = 0;
//print time of frames gathered
foreach(AudioFrame item in list_audio){
Console.WriteLine("audio " + (item.getTime() - rec_starting_time));
}
lock (list_video)
{
}
foreach (VideoFrame item in list_video)
{
Console.WriteLine("video " + (item.getTime() - rec_starting_time));
}
}
the another thread, where i get the time
if (write_stream.isRecording())
{
list_audio.Enqueue(new AudioFrame(relogio.ElapsedMilliseconds, audioBuffer));
}
event method
if (write_stream.isRecording())
{
list_video.Add(new VideoFrame(relogio.ElapsedMilliseconds, this.colorPixels));
}~
i dont know if this is relevant, but i start my stopwatch like this
public MainWindow()
{
InitializeComponent();
//some code
this.relogio = new Stopwatch();
relogio.Start();
}
Stopwatch is not threadsafe, particularly for 32-bit programs.
It uses the Windows API call QueryPerformanceCounter() to update a private long field. On 32-bit systems you could get a "torn read" when one thread reads the long value while another thread is updating it.
To fix that, you'd have to put a lock around access to the Stopwatch.
Also note that one some older systems there were bugs where inconsistent values could be returned from different threads calling QueryPerformanceCounter(). From the documentation:
On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). To specify processor affinity for a thread, use the SetThreadAffinityMask function.
I have never encountered this bug myself, and I don't think it's very common.
What results do you get with the following test program? The times should be mostly increasing in value, but you are liable to get one or two out of order just because their threads get rescheduled just after they've read a value and before they add it to the queue.
namespace Demo
{
class Program
{
Stopwatch sw = Stopwatch.StartNew();
object locker = new object();
ConcurrentQueue<long> queue = new ConcurrentQueue<long>();
Barrier barrier = new Barrier(9);
void run()
{
Console.WriteLine("Starting");
for (int i = 0; i < 8; ++i)
Task.Run(()=>test());
barrier.SignalAndWait(); // Make sure all threads start "simultaneously"
Thread.Sleep(2000); // Plenty of time for all the threads to finish.
Console.WriteLine("Stopped");
foreach (var elapsed in queue)
Console.WriteLine(elapsed);
Console.ReadLine();
}
void test()
{
barrier.SignalAndWait(); // Make sure all threads start "simultaneously".
for (int i = 0; i < 10; ++i)
queue.Enqueue(elapsed());
}
long elapsed()
{
lock (locker)
{
return sw.ElapsedTicks;
}
}
static void Main()
{
new Program().run();
}
}
}
Having said all that, the most obvious answer is that in fact you aren't sharing a single Stopwatch between the threads, but instead you have accidentally started a new one for each thread...
Related
I have to loop through code for specified time .I achieved it with DateTime
var time=DateTime.Now.AddMinutes((Convert.ToDouble(1)));
while(DateTime.Compare(DateTime.Now, time) <= 0)
{
console.write("some message..")
}
How do i achieve the same with Timer.Timer or thread.timer which is best approach..
Is it possible to write 10 times per sec?
Can anyone suggest. thank you
You could always use StopWatch, which is accurate and most appropriate for your scenario.
Action<long> action = (milliseconds) =>
{
Console.WriteLine("Running for {0}ms", milliseconds);
Stopwatch watch = new Stopwatch();
watch.Start();
while (watch.Elapsed.TotalMilliseconds <= milliseconds)
{
Console.WriteLine("ticks:{0}", DateTime.Now.Ticks);
Thread.Sleep(100);
}
Console.WriteLine("Done");
watch.Stop();
};
Task.Run(() => action(1000));
if you are going to make this work you need to make your program multithreaded,
See System.Threading and System.Threading.Task
Once you have your code executing in it's own thread, (using Thread, Task, Timer or any of the other variations in those namespaces) you can tell it to stop executing for a set amount of time, this is done by calling the Thread.Sleep or Task.Delay methods.
e.g.
Task.Run(()=>
{
do
{
//do something
await Task.Delay(100);
}
while(! exitCondition)
});
however you shouldn't count on this for exact timing as what you are doing is saying to the OS that this thread doesn't need to be executed for that amount of time, it doesn't mean the OS will pass it to the processor immediately on the time running out. depending on how busy the CPU is there can be quite a delay before your thread reaches the top of the waiting to process queue. if the timing is vitally important then i would set a lower time and check the clock before running
static void Main(string[] args)
{
System.Threading.Timer timer = null;
int counts = 0;
timer = new Timer((obj) =>
{
Console.WriteLine(counts);
if (++counts > 10)
timer.Dispose();
}, null, 100, 100);
for (;;) ;
}
will call the method dosomething() after 100ms, every 100ms
in the background, till timer.Dispose() is called;
this implementation will ofc never terminate as it is written here ;)
actually i have to create lots of threads to send pcap file using UDP protocol, when thread completely sends the pcap file it then sleep for some time. when i sleep thread to 420 seconds virtual memory gets full after creating more than 3100 threads and program throws a OutOfMemoryException.
i searched internet about this problem but found that a thread takes only 1MB to create and pcap file is just 60KB, and my 3100 threads are consuming more than 12GB(1.06*3100<12GB). on the other hand physical memory is not used more than 200MB. i have to create more than 5000 threads at the same time
what am i doing wrong? can anyone help me?
thanks
my code:
public static void send_pcap_file_with_single_port()
{
string callID = Call_ID;
try
{
//CREATING CONNECTION HERE
using (FileStream stream = new FileStream("g711a.pcap", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
for (Pos = 0; Pos < (StreamBytes - ChunkSize); Pos += ChunkSize)
{
//creating RTP_header here
stream.Read(RTP_payload, 0, ChunkSize);
//combining both the byte arrays
System.Buffer.BlockCopy(RTP_header, 0, Bytes_to_send, 0, RTP_header.Length);
System.Buffer.BlockCopy(RTP_payload, 0, Bytes_to_send, 16, RTP_payload.Length);
RTPpacket_queue.Enqueue(Bytes_to_send);
//RTP_handler.Send(Bytes_to_send, Bytes_to_send.Length, remote_EP);
}
//done processing here
stream.Close();
stream.Dispose();
RTP_count++;
GC.Collect();
}
System.Threading.Thread.Sleep(420000);
}
catch (Exception e)
{
//using (StreamWriter sw = new StreamWriter(stream_logFile))
//{
// sw.WriteLine(e.ToString());
//}
//send_BYE_message_toSIPp(client, "BYE", 5060, 2, callID);
Console.WriteLine(e.ToString());
}
}
creating threads here:
Thread RTP_sender = new Thread(new ThreadStart(send_pcap_file_with_single_port));
RTP_sender.Start();
In simple terms you exhaust you garbage collector by creating objects in long term pile (objects that survive longer then few seconds). Fix would be to free and recreate thread when it is needed.
In any case by default i5 has 2 cores, if you have 3 or more threads than they are running them on same cpu. Running 3000+ of them means 1500 each, it is not a problem unless they try to write in same place (in case they start blocking like hell).
To demonstrate you do not need 5000 permanent threads to accomplish something like this, I have created a sample program.
The program does not do much really but what it does do is that it creates 5000 objects, each of which creates a thread when it needs to do its work. There isn't any actual work being done other than simply sleeping for a random interval but still.
Just run the program, leave it running for a while and keep an eye on its memory use. You will see it is very much manageable while still actually doing work on 5000 objects.
You will probably need to actually be creative in applying this approach to your situation but you could do something along the lines of what I am doing.
namespace Test
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
public static class MainClass
{
public static Random sleeper = new Random ();
public static void Main (string[] args)
{
Stopwatch timer = new Stopwatch ();
List<WorkerClass> workload = new List<WorkerClass> ();
// Create a workload of 5000 objects
for (int i = 0; i < 5000; i++) {
workload.Add (new WorkerClass ());
}
int fires = 0;
// Start processing the workload
while (true) {
// We'll measure the time it took to go through the entire workload
// to illustrate that it does not take all that long.
timer.Restart ();
foreach (WorkerClass w in workload) {
// for each of the worker objects in the entire workload
// we decrease its internal counter by 1.
// Because after the loop is done, we sleep for 1 secondd
// that amounts to reducing the counter by 1 every second.
w.counter--;
if (w.counter == 0) {
fires++;
// Once the counter hits 0, do the work.
w.DoWork ();
}
}
timer.Stop ();
Console.WriteLine ("Processing the entire workload of {0} objects took {1} milliseconds, {2} workers actually fired.", workload.Count, timer.ElapsedMilliseconds, fires);
fires = 0;
Thread.Sleep (1000);
}
}
}
public class WorkerClass
{
public int counter = 0;
public WorkerClass ()
{
// When the worker is created, set its internal counter
// to a random value between 5 and 10.
// This is to mimic sleeping it for a random interval.
// Also see the primary loop in MainClass.Main
this.counter = MainClass.sleeper.Next (5, 10);
}
public void DoWork ()
{
// Whenever we do the work, we'll create a background worker thread
// that actually does the work.
BackgroundWorker work = new BackgroundWorker ();
work.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => {
// This simulates going back to sleep for a random interval, see
// the main loop in MainClass.Main
this.counter = MainClass.sleeper.Next (5, 10);
};
work.DoWork += (object sender, DoWorkEventArgs e) => {
// Simulate working by sleeping a random interval
Thread.Sleep (MainClass.sleeper.Next (2000, 5000));
};
// And now we actually do the work.
work.RunWorkerAsync ();
}
}
}
This code doesn't call function 200 times in 1 second, first time I get 167 calls, second time 201 but I don't get 200.
public Thread thread;
public Timer timer;
int i = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
timer = new Timer(Mess);
timer.Change(10000, 10000);
thread = new Thread(Calc);
thread.Start();
}
private void Mess(object state)
{
MessageBox.Show("Call in on second : " + (i / 10).ToString());
i = 0;
}
private void Calc(object obj)
{
while (true)
{
i++;
Thread.Sleep(5);
}
}
Its because of your scheduler wich manage the different threads in your processor. This process is not running all the time in your processor so strange behaviors can occur.
Programs using threads are rarely deterministic (it's why you get 167 for the first time ans 201 in the second time)
Because Windows is not a real-time operating system, it is difficult to achieve this kind of resolution.
The closest you are likely to get is by using the Windows API function CreateTimerQueueTimer(). This is a high-resolution timer, but it still might not be high enough resolution for your purposes.
You may still like to try it though. It's awkward to call from C# because it uses a callback function which Windows expects to be a native method. It's possible though, and here's an article on how to call it from C#.
I am writing a program that has several "Worker" objects going off and doing tasks that take as set amount of time. I have created a worker class with an internal timer that is working fine. However, when doing the "work" i will at times need to wait several seconds for a screen refresh (each worker is scraping data from a remote screen and doing some automation).
For those pauses, i don't want to sleep the thread, because as i understand it that will also
pause the timers on the other worker objects (my application is a single thread because, frankly, I'm brand new to C# and i didn't want to overreach). Is there another waiting function that i can use that doesn't actually hang the whole thread?
Some additional info:
Right now this is a console app, but i will eventually be building a UI form to provide feedback to the user on how the workers are doing
My timers are implemented using System.Timers and are working quite nicely
I am brand new to C# programming, this is my first project, so please use small words ;)
Using MS VS Express 2012 for Desktop (so whatever version of C# / .NET that is!)
Code below (the actual work will be done using the "startWorking" method, but nothing is implemented - this is just my sold build with timers working. Also, the main is just being used for testing multiple timers right now)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace Multi_Timers
{
//worker class that includes a timer
public class Worker
{
private Timer taskTimer;
private bool available = true;
private string workerName;
private string startWork;
private int workTime;
// properties
public bool isAvailable { get { return this.available; } }
public string name { get { return this.workerName; } }
// constructor
public Worker(string name)
{
this.workerName = name;
Console.WriteLine("{0} is initialized", name);
}
// start work timer
public void startWorking(int duration) {
if (this.available == true)
{
this.available = false;
this.taskTimer = new Timer();
this.taskTimer.Interval = duration;
this.taskTimer.Elapsed += new ElapsedEventHandler(doneWorking);
this.taskTimer.Enabled = true;
this.startWork = DateTime.Now.ToString();
this.workTime = duration / 1000;
}
else Console.WriteLine("Sorry, {0} was not available to work", this.workerName);
}
// Handler for timer
public void doneWorking(object sender, ElapsedEventArgs e)
{
Console.WriteLine("{0}: {1} / {2} min / {3}", this.workerName, this.startWork, this.workTime/60, e.SignalTime.ToLocalTime());
this.taskTimer.Enabled = false;
this.available = true;
}
}
//main program
class Program
{
static void Main(string[] args)
{
Random r = new Random();
// initialize worker(s)
Worker bob = new Worker("Bob");
Worker bill = new Worker("Bill");
Worker jim = new Worker("Jim");
// q to exit
while (true)
{
if (bob.isAvailable) {
bob.startWorking(r.Next(1 * 60, 150 * 60) * 1000);
}
if (bill.isAvailable)
{
bill.startWorking(r.Next(1 * 60, 150 * 60) * 1000);
}
if (jim.isAvailable)
{
jim.startWorking(r.Next(1 * 60, 150 * 60) * 1000);
}
}
}
}
}
Thank you for any help in advance! Reading examples from this community was definitely key in teaching myself a little bit of C# to get started with!
i don't want to sleep the thread, because as i understand it that will also pause the timers on the other worker objects
That is incorrect; it will not stop the timers.
my application is a single thread
No, actually, it's not. The timers will be creating and using other threads to implement their behavior. The Elapsed event handlers will be fired from a thread pool thread.
One major issue with your code is that your main method is doing a "busywait" on the three objects, constantly polling them asking if they're done. This is...expensive. It's basically like you're kids asking, "Are we there yet." a few hundred times a second. Wouldn't it be so much nicer if they just sat their waiting until you told them you were done! (That's quite possible, and a good possible option.)
One of the simpler solutions in this case would be to do the loop in the worker, not Main. Have the implementation of startWorking wrapped in a while loop, and have main just do a wait forever (i.e. Thread.Sleep(Timeout.Infinite);). More complex options would be having the workers provide a Task, event, or blocking wait (also called a "Join") method to indicate when they are finished.
The option you're considering, that of adding a Thread.Sleep of a little while in Main will help, but it's only telling your kids to ask you when you're there less often, rather than having them wait for you to tell them when you're there.
If you ever find yourself wanting to delay execution again in a different context you could consider an implementation like this:
private static void DelayExecution(Action action, TimeSpan delay)
{
TimeSpan start = DateTime.Now.TimeOfDay;
Thread t = new Thread(() =>
{
while (DateTime.Now.TimeOfDay < start.Add(delay))
{
//Block
}
action.Invoke();
});
t.Start();
}
private static void Main(string[] args)
{
DelayExecution(() => Console.WriteLine("Delayed Execution"), TimeSpan.FromSeconds(1));
Console.ReadLine();
}
(Any One There)
I am working on vehicle tracking system:-
I have n number of buses say
b1t1(start at 7 am and stop at 7 pm)
bt2 (start at 8 am and stop at 8 pm) and bt3 (start at 9 am and stop at 9 pm)
,where t is start time of a bus
now i have such such busses in a list.
now for each bus in a list i pickup one busobject and pass to method MyMethod(bus bt);what i want is ,I want to pass b1,b2,b3 to MyMethod(bus bt) and and of each bus say b1--start its own proccessing of MyMethod(bus bt)
and then for b2 --start its own proccessing of MyMethod(bus bt)
and then for b3----start its own proccessing of MyMethod(bus bt)
all b1 b2 b3 should start there own processing in parallel (must be thread safe---isn it approprate to use word thread safe i donn know)....
---I tried using thread but thread does not acces the method in parallel...
more explanation
i have only one method and will be passing bus object in a loop to MyMethod(bus bt) one by one ... but i want thread t1/t2...tn should access this method in parallel...because when thread for b1 is running simultinuously thread for b2 should run.
enter c public bool SchedulerEntryPointFunction()
{
Console.WriteLine("Scheduler is initiated !\n\n");
bool bSuccess = false;
Console.WriteLine("Got ActiveBuses and coresponding Paths!\n\n");
List<ActiveBusAndItsPathInfo> ActiveBusAndItsPathInfoList = BusinessLayer.GetActiveBusAndItsPathInfoList();
if (ActiveBusAndItsPathInfoList != null)
{
Thread[] threads = new Thread[ActiveBusAndItsPathInfoList.Count];
while (true)
{
foreach (ActiveBusAndItsPathInfo ActiveBusAndItsPathInfoObj in ActiveBusAndItsPathInfoList)
{
//Get curent time
//compare for time difference less than equal to 5 mins
if (ActiveBusAndItsPathInfoObj.isSMSThreadActive == false)
{
// Console.WriteLine("SMS Thread about to initiate!\n\n");
DateTime CurrentTime = System.DateTime.Now;
// TimeSpan CurrentTimespan = (TimeSpan)CurrentTime;
DateTime Bustime = Convert.ToDateTime(ActiveBusAndItsPathInfoObj.busObj.Timing);
//TimeSpan BustimeTimes = Bustime.TimeOfDay;
TimeSpan tsa = Bustime - CurrentTime;
// if(tsa.TotalMinutes > 0 && tsa.TotalMinutes < 5)
{
ActiveBusAndItsPathInfoObj.isSMSThreadActive = true;
***ThreadStart starter = delegate { SMSThreadEntryPointFunction(ActiveBusAndItsPathInfoObj); };
Thread t = new Thread(starter);
**// t.Start();
int indexOfCurrentActiveBusAndItsPathInfoObj = ActiveBusAndItsPathInfoList.IndexOf(ActiveBusAndItsPathInfoObj);
threads[indexOfCurrentActiveBusAndItsPathInfoObj] = new Thread(starter);
threads[indexOfCurrentActiveBusAndItsPathInfoObj].Start();
threads[indexOfCurrentActiveBusAndItsPathInfoObj].Join();***
}
}
}**
}
}
return bSuccess;
}
ode here
New Code:-
Still giving synchronization issue...
foreach (ActiveBusAndItsPathInfo ActiveBusAndItsPathInfoObj in ActiveBusAndItsPathInfoList)
{
//Get curent time
//compare for time difference less than equal to 5 mins
if (ActiveBusAndItsPathInfoObj.isSMSThreadActive == false)
{
DateTime CurrentTime = System.DateTime.Now;
DateTime Bustime = Convert.ToDateTime(ActiveBusAndItsPathInfoObj.busObj.Timing);
TimeSpan tsa = Bustime - CurrentTime;
if(tsa.TotalMinutes > 0 && tsa.TotalMinutes < 5)
{
ActiveBusAndItsPathInfoObj.isSMSThreadActive = true;
ThreadPool.QueueUserWorkItem(state => SMSThreadEntryPointFunction(ActiveBusAndItsPathInfoObj)
}
}
}
}
return bSuccess;
}
do i have to lock my method ...SMSThreadEntryPointFunction(ActiveBusAndItsPathInfoObj)
currently i am trying
ThreadPool.QueueUserWorkItem(new WaitCallback(SMSThreadEntryPointFunction), (object)ActiveBusAndItsPathInfoObj);
but giving an error:-"No overload for SMSThreadEntryPointFunction matches delegate system.thread.WaitCallback"
(Any One There)
ThreadPool.QueueUserWorkItem(state => MyMethod(bus1));
ThreadPool.QueueUserWorkItem(state => MyMethod(bus2));
...
The reason that you find your threads not executing in parallel is the line:
threads[indexOfCurrentActiveBusAndItsPathInfoObj].Join();
This causes the main thread to wait for the current bus thread to finish before the main thread continues. You may want to move the Join() call outside the loop that starts your threads or eliminate it all together. Start by commenting it out so you can see the effect it has.
Getting multithreaded code to work correctly can be challenging; and probably impossible if you don't have a good understanding of what's going on. I second Darin's suggestion that you read through the tutorial
Finally, it looks like what you're trying to do is run a simulation. A much simpler approach to this is to set up a priority queue of events ordered by simulation time. The main loop then simply pulls the first event off the queue, updates the simulated time to the event's time, and executes the event. Event handlers can schedule future events by pushing them on to the queue. You can find more about this idea by searching for information on "discrete event simulation".
You need to use a BackgroundWorker for your method and each method needs to run in it's own thread. So you'll have to assign each method it's own backgroundworker. You need to make sure that any resources that could be accessed by muyltiple threads at once are locked appropriately so that things are thread-safe.
Thread-safety means that multiple threads can use a resource with incurring data corruption or creating race conditions and/or deadlocks.