Can we use 2 timer events in a single application. I'm trying to use 2 timer events in a single application but the 2nd timer event is not working.... any one have an idea??? how to use 2 timer events in a single application....
Thanks in advance....
You can have as many numbers of timers as you want in your application. Just initialize them as if you'd initialize any other timer. Post the code you tried and we might be able to fix the issue.
var t1:Timer = new Timer(1000, 0);
t1.addEventListener(TimerEvent.TIMER, timerHandler1);
t1.start();
var t2:Timer = new Timer(500, 0);
t2.addEventListener(TimerEvent.TIMER, timerHandler2);
t2.start();
public function timerHandler1(event:TimerEvent):void {
trace("First timer triggered");
}
public function timerHandler2(event:TimerEvent):void {
trace("Second timer triggered");
}
It is not mandatory to use separate listeners; you can as well do:
public var t1:Timer;
public var t2:Timer;
t1 = new Timer(1000, 0);
t2 = new Timer(200, 0);
t1.addEventListener(TimerEvent.TIMER, timerHandler);
t2.addEventListener(TimerEvent.TIMER, timerHandler);
public function timerHandler2(event:TimerEvent):void {
if(event.target == t1)
trace("first timer");
else
trace("second timer");
}
Related
I am trying to port an Xamarin.Forms app to .NET MAUI but have run into the deprecation of Device.StartTimer, whilst this obviously currently still works in MAUI, I am interested to find out what the alternative is?
Currently I have a wrapper class as follows:
public void Start()
{
if (IsRunning)
{
return;
}
var wrapper = new TaskWrapper(Task, IsRecurring, true);
Tasks.Add(wrapper);
Device.StartTimer(Interval, wrapper.RunTask);
}
I tried replacing this with a System.Timers.Timer however this led to the issue of not being able to modify UI elements due to being on the wrong thread? The timer wrapper itself is used in multiple places so I can't use binding for example in this case either.
Is there actually a direct replacement for Device.StartTimer? Any assistance is greatly appreciated.
The Device timer is obsolete in MAUI.
You can create an IDispatcherTimer instance and subscribe to the Tick event like this:
var timer = Application.Current.Dispatcher.CreateTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += (s,e) => DoSomething();
timer.Start();
Depending on the context that you're using the timer in, you should use the MainThread.BeginInvokeOnMainThread() method to update UI elements:
void DoSomething()
{
MainThread.BeginInvokeOnMainThread(() =>
{
//Update view here
});
}
More info on UI main thread:
https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/main-thread
IDispatcherTimer timer;
timer = Dispatcher.CreateTimer();
timer.Interval = TimeSpan.FromMilliseconds(1000);
timer.Tick += (s, e) =>
{
label.Text = DateTime.Now.ToString();
};
timer.Start();
https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/button#press-and-release-the-button
My application adds multiple Runnable on FX thread, by calling Platform.runlater method, then, I want to do some calculations only when there is no additional Runnable is in the FX Platform queue.
But I don't know the right way, is there any event or callback mechanism to get the right time?
Currently I force the application thread to sleep randomly MILLISECONDS.
This is a bad idea from the start since you do not know what other code uses Platform.runLater. Also you should not rely on such implementation details; for all you know the queue could never be empty.
However you could post those Runnables using a custom class that keeps track of the number of Runnables and notifies you when all are done:
public class UpdateHandler {
private final AtomicInteger count;
private final Runnable completionHandler;
public UpdateHandler(Runnable completionHandler, Runnable... initialTasks) {
if (completionHandler == null || Stream.of(initialTasks).anyMatch(Objects::isNull)) {
throw new IllegalArgumentException();
}
count = new AtomicInteger(initialTasks.length);
this.completionHandler = completionHandler;
for (Runnable r : initialTasks) {
startTask(r);
}
}
private void startTask(Runnable runnable) {
Platform.runLater(() -> {
runnable.run();
if (count.decrementAndGet() == 0) {
completionHandler.run();
}
});
}
public void Runnable runLater(Runnable runnable) {
if (runnable == null) {
throw new IllegalArgumentException();
}
count.incrementAndGet();
startTask(runnable);
}
}
I have a page that doing something, it can take 1,2 hours or even more...
After a while I get request timed out, I want that this specific page will NOT get request timed out - ever(or at least 24 hours).
How do I do it?
Thanks.
You can make a thread with a signal in it to know it its still running or not.
I suggest to use a mutex signal because is the only one that can be the same across many pools and threads.
The thread code can be:
public class RunThreadProcess
{
// Some parametres
public int cProductID;
// my thread
private Thread t = null;
// start it
public Thread Start()
{
t = new Thread(new ThreadStart(this.work));
t.IsBackground = true;
t.SetApartmentState(ApartmentState.MTA);
t.Start();
return t;
}
// actually work
private void work()
{
// while the mutex is locked, the thread is still working
Mutex mut = new Mutex("WorkA");
try
{
mut.WaitOne();
// do thread work
all parametres are available here
}
finally
{
mut.ReleaseMutex();
}
}
}
And you call it as
Mutex mut = new Mutex("WorkA");
try
{
if(mut.WaitOne(1000))
{
// release it here to start it from the thread as signal
mut.ReleaseMutex();
// you start the thread
var OneAction = new RunThreadProcess();
OneAction.cProductID = 100;
OneAction.Start();
}
else
{
// still running
}
}
finally
{
mut.ReleaseMutex();
}
I am trying to write an application, but it is constantly crashing when using the uiimagepickercontroller. I thought that it might be because I was not disposing of the picker after each use, but it will often freeze up on first run as well. Usually I'll take a picture and it just freezes, never asking to "use" the picture.
Do you have any suggestions? Here is my code. Has anyone gotten this to work?
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
myPicker = new UIImagePickerController();
myPicker.Delegate = new myPickerDelegate(this);
myAlbumButton.Clicked += delegate {
if(UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)){
myPicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
myPicker.AllowsEditing = true;
this.PresentModalViewController (myPicker, true);
}else{
Console.WriteLine("cannot get album");
}
};
myCameraButton.Clicked += delegate {
if(UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
myPicker.SourceType = UIImagePickerControllerSourceType.Camera;
//myPicker.AllowsEditing = true;
this.PresentModalViewController (myPicker, true);
}else{
Console.WriteLine("cannot get camera");
}
};
}
private class myPickerDelegate : UIImagePickerControllerDelegate
{
private TestView _vc;
public myPickerDelegate ( TestView controller):base()
{
_vc = controller;
}
public override void FinishedPickingImage (UIImagePickerController myPicker, UIImage image, NSDictionary editingInfo)
{
// TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
_vc.myImageView.Image = image;
myPicker.DismissModalViewControllerAnimated(true);
}
}
Try to call your event handlers code from the main thread by using BeginInvokeOnMainThread().
So my issue was very similar.
Instead of having a delegate class, I had the delegates inline for the picker.
For some reason the app froze every time after talking the image, not stopping in any breakpoint after that.
The solution that worked for me was to use this book:
http://www.scribd.com/doc/33770921/Professional-iPhone-Programming-with-MonoTouch-and-NET-C
I'm tracking how fast does the text of a textArea change. If it changes faster than 500 ms then i don't want to do anything, but if it doesn't change in 500 ms, i want to call a method.
I tried like this:
public function textchangeListener(e : Event):void
{
if(((new Date).getTime() - changeTime)>500)
{
prepareText();
}
changeTime = (new Date).getTime();
}
This method is the event handler for text change.
But the problem is, if it changes only under 500 ms and after that it doesn't change, then my method won't be called. I make this for a better performance, so the prepareText() is called only when the user stops typing for 500 ms.
How about this...
Once you get the first text change event you can call a procedure like textTimeOut(). It will essentially work like this.
function textTimeOut():void
{
start a timer for 500 ms
set an event listener for it (your prepareText() function)
if textTimeOut is called again before the timer gets to 0,
reset the timer to 500 ms
}
I would use a setTimeout in the event handler and reset it everytime it changes:
var changeTimeout:Number = -1
function handler(e:Event):void {
if(changeTimeout != -1)
clearTimeout(changeTimeout)
changeTimeout = setTimeout(function():void{
changeTimeout = -1
prepareText();
}, 500)
}
So I used a timer. Thanks for the advice. This is what the end result is:
protected var timer:Timer = new Timer(300);
public function AdvancedTextArea()
{
super();
this.addEventListener(Event.CHANGE,textchangeListener);
timer.addEventListener(TimerEvent.TIMER,prepareText);
timer.repeatCount = 1;
}
public function textchangeListener(e : Event):void
{
if(timer.running)
{
timer.stop();
}
timer.start();
}