iOS Xamarin scheduled timer not firing - xamarin

We have a scheduler logic in an Xamarin (not Forms) project, which existed for quite some time and once worked. With one of the iOS upgrades (could be quite some time ago), the scheduler stopped firing events.
Why is the timer below not firing every 20 seconds? The app is active, the screen is on and I validated that the initialization code runs exactly once.
var interval = TimeSpan.FromSeconds(20);
Timer = NSTimer.CreateRepeatingScheduledTimer(interval, HandleScheduledEventMethod);
// ...
public void HandleScheduledEventMethod(NSTimer timer)
{
// never executed, except for each call to Timer.Fire()
}
I added it to the NSRunLoop as advised in the Apple docs, but that did not help either.
NSRunLoop.Main.AddTimer(Timer, NSRunLoopMode.Common);

AddTimer must be called on the main thread, it does not work when called on a background thread.
DispatchQueue.MainQueue.DispatchQueue(() => {
Timer = NSTimer.CreateRepeatingScheduledTimer(interval, HandleScheduledEventMethod);
NSRunLoop.Main.AddTimer(Timer, NSRunLoopMode.Common);
})

Related

Visual Studio Extension capturing event before stopping the Debug Process ( IVsDebugProcessNotify BeforeStopDebuggingProcess)

I am currently experimenting with Visual Studio Extensions.
I need to subscribe to an event that gets called before the actual Debugger is stopped.
Basically I am just Attaching to Managed Process (not running via F5). The problem is that Stop Debugging simply "detaches" the process, and the process continues running after that.
I plan to use this event to notify our process to exit
I have a class that implements IDebugEventCallback2, IVsDebuggerEvents and IVsDebugProcessNotify.
class MyDebugger : IDebugEventCallback2, IVsDebuggerEvents, IVsDebugProcessNotify
Inside this class, there is a member that subscribes to Debugger Events using IVsDebugger's AdviseDebugEventCallback() and AdviseDebuggerEvents() events.
_debugger = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger;
if (_debugger != null)
{
_debugger.AdviseDebugEventCallback(this);
_debugger.AdviseDebuggerEvents(this, out _debuggerEventsCookie);
}
I noticed however that the events fired from AdviseDebugEventCallback's Event() handler does not always gets called before the actual Stop Debugging (next few lines after the breakpoint are still executed after I clicked Stopped Debugging). Around 4 or out of 5 times, the event from IDebugCustomEvent110 (riidEvent of 2615D9BC-1948-4D21-81EE-7A963F20CF59) gets called before any line from the attached process gets further executed. I still have to digest the details of the events fired in the Event() handler, but looking at the breakpoints, seems like I could not rely on this as it only works as per my expectation around 4 out of 5 times.
I am currently looking at the BeforeStopDebuggingProcess() method inside IVsDebugProcessNotify.
However, I don't know how to "Subscribe" or "Advice" from this interface.
Any advice how? There isn't much Google result about this topic.
Thank you!
I found something hacky, please comment if this is recommended or not.
I got some hint about the CommandEvents from this post:
How do I know from my VSIX that a build will be followed by a Debug session?
First, I subscribed to the commandEvents of DTE.
DTE dte = await serviceProvider.GetServiceAsync(typeof(DTE)) as DTE;
if (dte != null)
{
events = dte.Events;
commandEvents = events.CommandEvents;
commandEvents.BeforeExecute += OnBeforeExecute;
}
Then, inside OnBeforeExecute, I am hardcoding this particular GUID and ID which I observed to be fired whenever Stop Debugging is clicked (amongst many other events).
If I put Thread.Sleep() of 30 seconds inside this handler, the Stop Button of the Visual Studio freezes for 30 seconds (eventually the entire Visual Studio) :-) The code will resume after 30 seconds of wait.
private void OnBeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
if (Guid == "{5EFC7975-14BC-11CF-9B2B-00AA00573819}" && ID == 179)
{
// Stop command is detected
Trace.WriteLine($"[OnBeforeExecute] {Guid} --- {ID} Stop Command Detected");
System.Threading.Thread.Sleep(30000);
}
}

It is possible background works for every 1 minutes in ios?

Hello firstly I am so sorry about my bad english level.
I have an application.
Basically my application works for every 1 minutes use get method for getting some json data from server.
It is possible in android side and i created with foreground service.
But for xamarin.ios side how i can create?
actually my question is it is possible for in ios?
Before doing that , you can have a research with backgrond tasks in iOS .
The biggest change in iOS 7 with regard to background tasks is not how the tasks are implemented, but when they run.
Recall that pre-iOS 7, a task running in the background had 600 seconds to complete. One reason for this limit is that a task running in the background would keep the device awake for the duration of the task:
iOS 7 background processing is optimized for longer battery life. In iOS 7, backgrounding becomes opportunistic: instead of keeping the device awake, tasks respect when the device goes to sleep, and instead do their processing in chunks when the device wakes up to handle phone calls, notifications, incoming emails, and other common interruptions. The following diagram provides insight into how a task might be broken up:
Because the task run time is not longer continuous, tasks that perform network transfers must be handled differently in iOS 7. Developers are encouraged to use the NSURlSession API to handle network transfers. The next section is an overview of background transfers.
If you can keep the device not be killed , you can have a try with using System.Threading.Timer class to use Timer to implement what your want:
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
private static Timer timer;
static void Main(string[] args)
{
var timerState = new TimerState { Counter = 0 };
timer = new Timer(
callback: new TimerCallback(TimerTask),
state: timerState,
dueTime: 1000,
period: 2000);
while (timerState.Counter <= 10)
{
Task.Delay(1000).Wait();
}
timer.Dispose();
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
}
private static void TimerTask(object timerState)
{
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
var state = timerState as TimerState;
Interlocked.Increment(ref state.Counter);
}
class TimerState
{
public int Counter;
}
}
In addition , the first doc share the Background Transfers notes .The backbone of background transfers in iOS 7 is the new NSURLSession API.

JavaFX stop() method freezing GUI

I have an application that uses the stop() method to do cleanup tasks (close threads, free up resources, etc). That cleanup is all encapsulated into one Task object and that task's progress is bound to ProgressBar and Label components, like so (note that the headless value is obtained from reading a config file and just means that the user has chose to run the app with no GUI, in this case it's obviously set to false) :
CompleteShutdownTask task = new CompleteShutdownTask();
if (!headless)
{
ProgressBar progressBar = statusBar.getProgressBar();
progressBar.progressProperty().unbind();
progressBar.progressProperty().bind(task.progressProperty());
Label progressLabel = statusBar.getProgressLabel();
progressLabel.textProperty().unbind();
progressLabel.textProperty().bind(task.messageProperty());
}
I know this logic works because I also have an initialization task bound to these components in the exact same way when the program starts and that works fine. My issue is that the task runs fine but the GUI becomes completely unresponsive while the stop() method runs. I even have a super simple method to disable the buttons while this runs and even that doesn't work, the GUI is completely frozen while stop() executes.
Is it normal for this sort of GUI freezing to occur while the stop() method executes?

android: AsyncTask onPostExecute keep working even if start new activity on doInBackground

i am building an application for clients to get questions from server and answer it, if the server doesn't have questions i want to go to new screen and print message that try again in few minutes, getting questions is in AsyncTask , if the server doesn't have questions , it will sends in the header of the responds, a header isFindAQuestion with the value false, here is the code on client to ensure if false , i print on LogCat and i see the message = false, but my problems that even if i start new activity with the intent, this activity keep working and show me exception and it is null pointer exception because on the onPostExceute will take a parmeter null and try to process it, i put finish() in the end of false statement but doesn't finish the activity
if (response.getFirstHeader("isFindAQuestion").getValue()
.toString().equals("false")) {
Log.d("message", "false");
Bundle basket = new Bundle();
basket.putString("Message", "sorry no enought questions");
Intent goToAnswerQuestion = new Intent(AnswerQuestion.this,
FinishTime.class);
goToAnswerQuestion.putExtras(basket);
startActivity(goToAnswerQuestion);
finish();
}
Editis it because AsyncTask is working on thread so if the activity is finished, that thread will keep working? and if so how can i stop that thread?
doInBackground is not executed in the UI thread, but in a separeted thread:
invoked on the background thread immediately after onPreExecute()
finishes executing. This step is used to perform background
computation that can take a long time.
If you want to stop your background operation and perform some activities on the UI thread the better thing is to call cancel() and then perform all the stuff you want in the onCancelled callback wich is executed on the UI thread.
From the AsyncTask documentation:
A task can be cancelled at any time by invoking cancel(boolean).
Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)
protected void onCancelled (Result result)
Runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished.
The default implementation simply invokes onCancelled() and ignores the result. If you write your own implementation, do not call super.onCancelled(result).

Windows Forms: thread safe access to GUI?

in the last hours I've struggled with delegates and accessing Windows Forms controls (C++) where I've used this tutorial (the first thread safe method): http://msdn.microsoft.com/en-us/library/ms171728.aspx#Y190
Changing TextBoxes and Labels works perfectly but when I want to show or hide the whole GUI from another thread this fails.
I use the following methode (which is part of the GUI class):
System::Void UI::showUI(boolean value) {
if (this->InvokeRequired) {
SetTextDelegate^ d = gcnew SetTextDelegate(this, &UI::showUI);
this->Invoke(d, gcnew array<Object^> { value });
} else {
if (value == true)
this->Show();
else
this->Hide();
}
}
In the first call the if-clause is true so Invoke is called. But usually the showUI method should be called a second time automatically where the if-clause returns false, but this is not happening. So the GUI is neither shown nor hiden.
Is it necessary to show/hide the GUI with a delegate or can I do it from every possible thread? If a delegate is necessary, why is showUI not executed a second time?
Thanks,
Martin
edit: okay the name SetTextDelegate is not appropriate but this is not the point...
This is a pretty standard case of deadlock, not uncommon with Control::Invoke(). It can only proceed if the UI thread is not busy. Use Debug + Windows + Threads and double-click the Main thread. Look at the call stack to see what it is doing. The typical case is that it is blocking, waiting for the thread to finish the job. That will never happen since the thread can't complete until the Invoke() call returns.
Don't block the UI thread.
Consider using BackgroundWorker, its RunworkerCompleted event is nice to do stuff after the thread completes, removing the need to block.

Resources