I have a method that detects beacons after each 30 seconds. The scenario is as follows:
The scan period of beacons is 60 seconds.
The waiting period before the next scan is 30 seconds.
The above settings have already been defined in the BeaconDectector class. Now to display the beacons scanned on my UI, I have the following:
private void Button_Clicked(object sender, EventArgs e)
{
bool start = true;
while (start) {
beaconsFound = StartDetection();
Device.BeginInvokeOnMainThread(() =>
{
listView.ItemsSource = beaconsFound;
});
}
}
The StartDetection contains the logic that take place every 30 seconds and the scan period is 60 seconds. How can I ensure that I don't miss any beacons to get displayed on my listview?
Please advise. Thank you.
You should definitely not use active waiting while(start) to manage this. A better solution would be a Timer. You can see the basics for this in this blogpost.
Furthermore, ensure you are not running any long running code on the UI thread (which is what Button_Clicked runs on). Ideally, your timer should fire each 30 seconds, start a new Task for the detection and use Device.BeginInvokeOnMainThread to update the list when appropriate.
Related
I have an application, which is to repeat the numbers what I hear then record the digits what I read. The numbers are 0,1,2,3,4,5,6,7,8,9. I use a for loop to play these numbers with a text to speech skill, which is from a third party.
For the recording part, I have to put it in a separate thread by the third party requirement. To record the voice, the method is likely:
recordVoiceResource.Record(fileName);
To stop it, use:
recordVoiceResource.Stop();
Now I find sometimes my recording is 0 second, which means the code perhaps doesn't reach Record line. Sometimes it only has 2 seconds. I believe the thread schedule is wrong.
private ManualResetEvent terminate = new ManualResetEvent(false);
PlayTTS("Please repeat the following numbers as you hear them.");
Thread t = new Thread(() => RecordNumbers());
t.Start();
Thread.Sleep(2000);
terminate.Set();
terminate.WaitOne();
PlayNumbers();
recordVoiceResource.Stop();
The thread method is:
private void RecordNumbers()
{
recordVoiceResource = TelephonyServer.GetVoiceResource();
recordVoiceResource.MaximumSilence = 1;
recordVoiceResource.MaximumTime = 30;
// Start recording what I read from I heard
recordVoiceResource.Record(fileName);
}
To playNumbers,
private void PlayNumbers()
{
foreach (var item in numbers)
{
try
{
vr.PlayTTS(item.ToString()); // will be 0,1,2,...9
Thread.Sleep(2000);
}
According to your comment, the property MaximumSilence gets or sets the maximum silence in seconds that will be allowed until termination of the next voice function. You are setting it to one second, starting the recording, and then sleeping for two seconds before beginning playback that prompts the user to say something. Do you see the problem here? Assuming the mic doesn't pick up some unrelated speech during that period, the recording will stop before the playback even begins.
Since there is a 2-second gap between number playback, you probably need to set MaximumSilence to several seconds.
That is, of course, assuming your intention was to capture a single recording of the user speaking all the numbers (which is how your code is written). If you want to capture the spoken numbers individually, then you may need to schedule and synchronize separate recordings as each number is played back. You may want to double-check the API to make sure your solution is what you intended.
It is very likely your problem is causing due to Thread.Sleep(). Use a timer instead:
System.Timers.Timer Record = new System.Timers.Timer();
Record.Interval = 2000;
Record.Elapsed += new System.Timers.ElapsedEventHandler(Record_Elapsed);
void Record_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Record.Enabled=false;
PlayNumbers();
recordVoiceResource.Stop();
}
And set:
Thread t = new Thread(() => RecordNumbers());
t.Start();
Record.Enabled=true;
I have a list of of StringsDouble called Messages.
The code for the class is below:
public class StringsDouble
{
public string Sender {get; set;}
public string Message {get; set;}
public DateTime Time {get; set;}
}
every time my app receives a new message. I update the List and i store the time of the latest message sent for the user sending that message.
what i want to do is, every 5 minutes the app should go through the list.
and for every item in the list it should get the time property and get the current system time , and check to see if the difference is more than 30 minutes. If it is, it should delete that item from the list.
How can i accomplish this?
I believe i need to use a background task, but how can i schedule it to run every 5 minutes?
You can use DispatcherTimer on UI thread:
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMinutes(5);
timer.Tick += (sender, e) =>
{
//...
};
timer.Start();
or ThreadPoolTimer on a background thread:
ThreadPoolTimer threadPoolTimer = ThreadPoolTimer.CreatePeriodicTimer((source) =>
{
//...
}, TimeSpan.FromMinutes(5));
There is no way to run your backgroundtask every 5 minutes.
Maybe push notification can help you? It has a price as you can guess but you can send them any time, any frequency.
http://code.msdn.microsoft.com/windowsapps/Windows-8-Modern-Style-App-Samples
You can download these samples, there is a sample code for push notifications too.
This link (with code) seems to suggest that you can spread out the 2 seconds of CPU that is assigned to your app every 15 mins. You can therefore run some code in your background task more frequently than every 15 mins:
https://developer.qualcomm.com/blog/windows-8-background-tasks-part-3-make-most-cpu-usage-quota
I've tried to search for this on google and stackoverflow, but I'm not sure what to call it, so I can't find it.
How would I make a "loop" for the C# program, that runs every, say, 100 milliseconds? Similar to what Minecraft calls "ticks", or GameMaker calls "steps".
I can't figure out how to do this. I'm using visual studio, and I have a main window. There are things that I want to execute constantly, so I'm trying to figure out how to make a "step" or "update" function.
If you want it to run for 100 ms you would do this
System.Timers.Timer timer = new System.Timers.Timer(100);
public void Initialize(object sender, EventArgs e)
{
timer.Elapsed+=Elapsed;
}
public void Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//do stuff
}
Something else you can do, however I don't think this one is as efficient
using System.Threading;
Thread th = new Thread(new ThreadStart(delegate
{
while (true)
{
Thread.Sleep(100);
//do stuff
}
}));
Or, you can download monogame to make more elaborate games in c#
http://www.monogame.net/
It has its own gameTime control.
You could use the Timer control which can be set to tick at a given interval. The interval property is in Milliseconds so you would need Timer1.Interval = 100;
Are you thinking of a Timer?
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Generates recurring events in an application.
I would like to know how to run a c# program in background every five minute increments. The code below is not what I would like to run as a background process but would like to find out the best possible method to do this using this code so that I can implement it on another code. so this process should run after a five minute increment. I know I could use threads to do so, but dont really now how to implement this. I know this is the best way How to run a console application on system Startup , without appearing it on display(background process)? this to run in the background, but how would I have the code running in five minute increments
class Program
{
static void Main(string[] args)
{
Console.Write("hellow world");
Console.ReadLine();
}
}
This app should run continuously, putting out a message every 5 minutes.
Isn't that what you want?
class Program
{
static void Main(string[] args)
{
while (true) {
Console.Write("hellow world");
System.Threading.Thread.Sleep(1000 * 60 * 5); // Sleep for 5 minutes
}
}
}
Why not just use Windows Task Scheduler?
Set it to run your app at the desired interval. It's perfect for this sort of job and you don't have to mess about with forcing threads to sleep which can create more problems that it solves.
How about using a System.Windows.Threading.DispatcherTimer?
class Program
{
static void Main(string[] args)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 5, 0); // sets it to 5 minutes
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
static void timer_Tick(object sender, EventArgs e)
{
// whatever you want to happen every 5 minutes
}
}
Probably the simplest way to "fire" a new process every X minutes is to use Windows Task Scheduler.
You could of course do something similar programmatically, e.g. create your own service, that starts the console application every X minutes.
All this under assumption you actually want to close the application before the next iteration. Alternatively, you might just keep it active the whole time. You might use one of the timer classes to fire events periodically, or even a Thread.Sleep in a very simplified scenario....
I use the following code in a asp.net website.
On application init i call InitializeTimer() once.
The goal of the code was to run DoWork() once every hour (1 time per hour) .
I also wanted the code to execute on different time every loop so i added the random part.
The result i got was werid , i can not find a explaination why is happens.
The code executed the function after 2hrs , then again after 2hrs , then after 3hrs , then after 2hrs , and 2hrs again.****
Can anybody explain the reason?
using System.Timers;
....
private static random = new Random();
....
public static void InitializeTimer()
{
tTimer = new Timer();
tTimer.AutoReset = true;
tTimer.Interval = TimeSpan.FromHours(1.0).TotalMilliseconds;
tTimer.Elapsed += new ElapsedEventHandler(ClassName1.tMailer_Elapsed);
tTimer.Start();
}
private static void tTimer_Elapsed(object sender, ElapsedEventArgs e)
{
tTimer.Interval += random.Next(-5, 5);
DoWork();
}
Update:
Please don't post "use windows service" , or "scheduled task".
My question is for the following code I'm not looking for better alternatives.
Also , during this test (10hrs) , website was with high traffic , iis pool did not restart!
Based on the following MSDN: (http://msdn.microsoft.com/en-us/library/system.timers.timer.interval.aspx)
If the interval is set after the Timer
has started, the count is reset. For
example, if you set the interval to 5
seconds and then set the Enabled
property to true, the count starts at
the time Enabled is set. If you reset
the interval to 10 seconds when count
is 3 seconds, the Elapsed event is
raised for the first time 13 seconds
after Enabled was set to true.
Is it possible that re-setting the interval in the elapsed function is the cause of the problem?
Meaning that when tTimer_Elapsed function is called the count is 1hr(min a few millisecond)
and my code "tTimer.Interval += random.Next(-5, 5);" is adding another full hour to the Interval?
ASP.NET applications will get shut down when not in use. If someone hits your site, and then no more hits, it can get shut down. Your timer won't fire.
For this type of maintenance work you want to use a windows scheduled task or windows service.
Check this out... Jeff Atwood actually discussed something similar. I guess it worked, but according to Jeff the site outgrew this method so they went to a dedicated task.
Since .net 4.5.2, there is a class called HostingEnvironment, it can do what you're asking, here is how to use:
https://blog.mariusschulz.com/2014/05/07/scheduling-background-jobs-from-an-asp-net-application-in-net-4-5-2
The HostingEnvironment.QueueBackgroundWorkItem method lets you
schedule small background work items. ASP.NET tracks these items and
prevents IIS from abruptly terminating the worker process until all
background work items have completed.
I second Sams suggestion of using windows scheduled task to hit a page every hour. I tried and tried to get mine to work and it sort of worked. I went to a scheduled task and it has never failed.