Race condition GCD - ios

I want to keep alive main thread to not freeze my application. But i don't know how to make non race condition with my async task. So i need wait my async task, but without blocking mainQueue.
public override bool ShouldPerformSegue(string segueIdentifier, NSObject sender)
{
bool isAlowed = false;
ActivityIndicator.StartAnimating();
DispatchQueue.GetGlobalQueue(DispatchQueuePriority.High).DispatchAsync(()=>
{
NSThread.SleepFor(2);
isAlowed = true;
});
return isAlowed;
}

Rather than initiating the segue and then trying to determine if the segue should be performed, asynchronously, simply handle the user interaction without triggering the segue, determine if the segue should be performed and then initiate the segue.
I can't give you exact code since I don't know Xamarin well enough, but the pseudo-code is something like:
handleHandleButtonTap() {
initiateBackgroundCheckWithHandler( isAllowed(bool) {
if isAllowed {
performSegueWithIdentifer("SomeSegue") // You need to dispatch this on the main queue
}
})
}
Xamarin / C# example:
void SomeButton_TouchUpInside(object sender, EventArgs e)
{
bool isAllowed = false;
InvokeInBackground(() =>
{
// Do some task... and optionally assign isAllowed to true...
if (isAllowed)
DispatchQueue.MainQueue.DispatchAsync(() => PerformSegue("SomeSegue", this));
});
}

Related

Is Orleans reminder execution interleaved?

If there are two different reminders on the same grain activation to be fired at the same point, given that grain execution context is single-threaded, will both reminders be executed and interleaved at the same time?
Also, is the reminder execution limited by the default 30s timeout ?
Reminders are invoked using regular grain method calls: the IRemindable interface is a regular grain interface. IRemindable.ReceiveReminder(...) is not marked as [AlwaysInterleave], so it will only be interleaved if your grain class is marked as [Reentrant].
In short: no, reminder calls are not interleaved by default.
Reminders do not override the SiloMessagingOptions.ResponseTimeout value, so the default execution time will be 30s.
If you have a reminder that might need a very long time to execute, you can follow a pattern of starting the long-running work in a background task and ensuring that it is still running (not completed or faulted) whenever the relevant reminder fires.
Here is an example of using that pattern:
public class MyGrain : Grain, IMyGrain
{
private readonly CancellationTokenSource _deactivating = new CancellationTokenSource();
private Task _processQueueTask;
private IGrainReminder _reminder = null;
public Task ReceiveReminder(string reminderName, TickStatus status)
{
// Ensure that the reminder task is running.
if (_processQueueTask is null || _processQueueTask.IsCompleted)
{
if (_processQueueTask?.Exception is Exception exception)
{
// Log that an error occurred.
}
_processQueueTask = DoLongRunningWork();
_processQueueTask.Ignore();
}
return Task.CompletedTask;
}
public override async Task OnActivateAsync()
{
if (_reminder != null)
{
return;
}
_reminder = await RegisterOrUpdateReminder(
"long-running-work",
TimeSpan.FromMinutes(1),
TimeSpan.FromMinutes(1)
);
}
public override async Task OnDeactivateAsync()
{
_deactivating.Cancel(throwOnFirstException: false);
Task processQueueTask = _processQueueTask;
if (processQueueTask != null)
{
// Optionally add some max deactivation timeout here to stop waiting after (eg) 45 seconds
await processQueueTask;
}
}
public async Task StopAsync()
{
if (_reminder == null)
{
return;
}
await UnregisterReminder(_reminder);
_reminder = null;
}
private async Task DoLongRunningWork()
{
// Log that we are starting the long-running work
while (!_deactivating.IsCancellationRequested)
{
try
{
// Do long-running work
}
catch (Exception exception)
{
// Log exception. Potentially wait before retrying loop, since it seems like GetMessageAsync may have failed for us to end up here.
}
}
}
}

RxJava- Turn Observable into Iterator, Stream, or Sequence

I know this breaks a lot of Rx rules, but I really like RxJava-JDBC and so do my teammates. Relational databases are very core to what we do and so is Rx.
However there are some occasions where we do not want to emit as an Observable<ResultSet> but would rather just have a pull-based Java 8 Stream<ResultSet> or Kotlin Sequence<ResultSet>. But we are very accustomed to the RxJava-JDBC library which only returns an Observable<ResultSet>.
Therefore, I am wondering if there is a way I can turn an Observable<ResultSet> into a Sequence<ResultSet> using an extension function, and not do any intermediary collection or toBlocking() calls. Below is all I have so far but my head is spinning now trying to connect push and pull based systems, and I cannot buffer either as the ResultSet is stateful with each onNext() call. Is this an impossible task?
import rx.Observable
import rx.Subscriber
import java.sql.ResultSet
fun Observable<ResultSet>.asSequence() = object: Iterator<ResultSet>, Subscriber<ResultSet>() {
private var isComplete = false
override fun onCompleted() {
isComplete = true
}
override fun onError(e: Throwable?) {
throw UnsupportedOperationException()
}
override fun onNext(rs: ResultSet?) {
throw UnsupportedOperationException()
}
override fun hasNext(): Boolean {
throw UnsupportedOperationException()
}
override fun next(): ResultSet {
throw UnsupportedOperationException()
}
}.asSequence()
I'm not sure that's the easiest way to achieve what you want but you can try this code. It converts an Observable to an Iterator by creating a blocking queue and publishing all events from the Observable to this queue. The Iterable pulls events from the queue and blocks if there're none. Then it modify its own state depending on received current event.
class ObservableIterator<T>(
observable: Observable<T>,
scheduler: Scheduler
) : Iterator<T>, Closeable {
private val queue = LinkedBlockingQueue<Notification<T>>()
private var cached: Notification<T>? = null
private var completed: Boolean = false
private val subscription =
observable
.materialize()
.subscribeOn(scheduler)
.subscribe({ queue.put(it) })
override fun hasNext(): Boolean {
cacheNext()
return !completed
}
override fun next(): T {
cacheNext()
val notification = cached ?: throw NoSuchElementException()
check(notification.isOnNext)
cached = null
return notification.value
}
private fun cacheNext() {
if (completed) {
return
}
if (cached == null) {
queue.take().let { notification ->
if (notification.isOnError) {
completed = true
throw RuntimeException(notification.throwable)
} else if (notification.isOnCompleted) {
completed = true
} else {
cached = notification
}
}
}
}
override fun close() {
subscription.unsubscribe()
completed = true
cached = null
}
}
You can use the following helper function:
fun <T> Observable<T>.asSequence() = Sequence { toBlocking().getIterator() }
The observable will be subscribed to when the sequence returned is called for iterator.
If an observable emits elements on the same thread it was subscribed to (like Observable.just for example), it will populate the buffer of the iterator before it gets a chance to be returned.
In this case you might need to direct subscription to the different thread with a call to subscribeOn:
observable.subscribeOn(scheduler).asSequence()
However, while toBlocking().getIterator() doesn't buffer all results it could buffer some of them if they aren't consumed timely by the iterator. That might be a problem if a ResultSet gets somehow expired when the next ResultSet arrives.

How can I unit test async methods on the UI Thread with Xamarin iOS TouchRunner

I have successfully been able to get the following nested async unit test working using TouchRunner (NUnitLite) in Xamarin:
[Test]
[Timeout (Int32.MaxValue)]
public async void NestedAsyncFail()
{
await Task.Run(async() =>
{
await Task.Delay(1000);
});
Assert.AreEqual(1, 0);
}
[Test]
[Timeout (Int32.MaxValue)]
public async void NestedAsyncSuccess()
{
await Task.Run(async() =>
{
await Task.Delay(1000);
});
Assert.AreEqual(1, 1);
}
Results: http://i.stack.imgur.com/5oC11.png
However, what if I want to test an async method that needs to perform some logic but also make some UI changes and thus, be executed on the main thread? Below is my attempt at doing this however, there are some issues...
[Test]
[Timeout (Int32.MaxValue)]
public void TestWithUIOperations()
{
bool result = false;
NSObject invoker = new NSObject ();
invoker.InvokeOnMainThread (async () => {
await SomeController.PerformUIOperationsAsync ();
result = true;
});
Assert.True (result);
}
With the Timeout attribute the TouchRunner freezes probably due to some thread locking. Without the Timeout attribute, the assertion returns false - I believe this is due to the async method not awaiting properly?
Can anyone advise where I'm going wrong and/or how this can be accomplished?
My use of the Timeout attribute in the first test is explained here:
https://bugzilla.xamarin.com/show_bug.cgi?id=15104
I've used an AutoResetEvent in situations like these to test our asynchronous startup routines:
[Test]
public void CanExecuteAsyncTest()
{
AutoResetEvent resetEvent = new AutoResetEvent(false);
WaitHandle[] handles = new WaitHandle[] { resetEvent};
bool success = false;
Thread t = new Thread(() => {
Thread.Sleep(1000);
success = true;
resetEvent.Set();
});
t.Start ();
WaitHandle.WaitAll(handles);
Assert.Equal(true, success);
}
If you're testing UI functionality, you may be better using Calabash or a related framework that is dedicated to testing UI flow.

How to listen for a keyboard event in dart programming

I'm new to google dart and been trying to learn it for a day now. I'm pretty novice to programming in general and I'm trying to read the documentation; however, I feel a bit overwhelmed.
I would like to know the most proper method of creating a interaction for spacebar here key. When one would push spacebar, it would toggle between function void startwatch() , void resetwatch()
I believe this is the correct documentation page also documentation for keyboardEventController
void main() {
}
void startwatch() {
mywatch.start();
var oneSecond = new Duration(milliseconds:1);
var timer = new Timer.repeating(oneSecond, updateTime);
}
void resetwatch() {
mywatch.reset();
counter = '00:00:00';
}
Any further information needed I'll try to respond immediately. Thnk you so much for your help.
To listen to keyboard events and toggle between startwatch() and resetwatch():
void main() {
var started = false;
window.onKeyUp.listen((KeyboardEvent e) {
print('pressed a key');
if (e.keyCode == KeyCode.SPACE) {
print('pressed space');
if (started) {
resetwatch();
} else {
startwatch();
}
started = !started; // A quick way to switch between true and false.
}
});
}
window is an instance of Window class. It's automatically provided for you.
There's also a handy class called KeyEvent, which attempts to eliminate cross-browser inconsistencies. These inconsistencies are usually related to special keys.

Cancel a timer in BlackBerry - Java

I am working with a BlackBerry App that has a number of timers in it to schedule sending reports to the server platform. It is all working fine until I changed the logic to prioritize reports. Therefore, now I am checking if, for instance, Report A is switched on and the user activates Report B as well, then only Report B should go through and Report A should halt UNTIL B is activated. Once B is deactivated (timer cancelled), Report A should resume. However, even when the code loops in the cancel timer task code, Report A continues to go through while B is still activated.
FieldChangeListener reportingListener = new FieldChangeListener() {
public void fieldChanged(Field field, int context)
{
try {
if (field == slider) {
int i = slider.getValue();
if(i==0)
lblInterval.setText(1+" minute");
if(i==1)
lblInterval.setText(2+" minutes");
if(i==2)
lblInterval.setText(5+" minutes");
if(i==3)
lblInterval.setText(10+" minutes");
if(i==4)
lblInterval.setText(15+" minutes");
if(i==5)
lblInterval.setText(30+" minutes");
if(i==6)
lblInterval.setText(1+" hour");
if(i==7)
lblInterval.setText(2+" hours");
if(i==8)
lblInterval.setText(6+" hours");
if(i==9)
lblInterval.setText(12+" hours");
if(i==10)
lblInterval.setText(24+" hours");
setSliderPosition(i);
value=setLblIntervalValue(i);
value2=setGpsTimerIntervalValue(i);
gpsReportValue=lblInterval.getText();
gpsIntervalValue1=setGpsTimerIntervalValue(i);
}
if (PersistentStoreHelper.persistentHashtable.containsKey("image"))
{
boolean trackONOFFImage = ((Boolean) PersistentStoreHelper.persistentHashtable.get("image")).booleanValue();
if(trackONOFFImage==true)
{
if (PersistentStoreHelper.persistentHashtable.containsKey("panic"))
{
boolean panicImage = ((Boolean)PersistentStoreHelper.persistentHashtable.get("panic")).booleanValue();
if(panicImage==true)
{
MyScreen.currentlyReporting.setText("PANIC ALARM TRIGGERED");
if (PersistentStoreHelper.persistentHashtable.containsKey("tabTrackValid"))
{
boolean trackingTab = ((Boolean)PersistentStoreHelper.persistentHashtable.get("tabTrackValid")).booleanValue();
if(trackingTab==false)
{
trackSlider.cancel();
}
PersistentStoreHelper.persistentHashtable.put("tabTrackValid", Boolean.TRUE);
}
}
else
{
//int gpsIntervalValue1=setGpsTimerIntervalValue(i);
if (PersistentStoreHelper.persistentHashtable.containsKey("gpsTimerIntervalValue"))
{
String intervalValue=((String)PersistentStoreHelper.persistentHashtable.get("gpsTimerIntervalValue"));
if(gpsIntervalValue1==Integer.parseInt(intervalValue))
{
//do nothing
}
else
{
trackSlider = new TimerTask() {
public void run() {
try {
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run() {
//Dialog.alert("Invalid login details");
}
});
sendTrackingReport();
} catch (Exception e) {
Dialog.alert("Unable to track at the new interval set");
}
}
};
//trackSlider.run();
trackingTimerSlider.scheduleAtFixedRate(trackSlider , 0, gpsIntervalValue1);
PersistentStoreHelper.persistentHashtable.put("tabTrackValid", Boolean.FALSE);
}
}
}
}
}//this
}
} catch (IllegalStateException e) {
//Dialog.alert("CANCEL TRACK1");
e.printStackTrace();
} catch (NullPointerException e) {
//Dialog.alert("CANCEL TRACK2");
e.printStackTrace();
}
}
};
NOTE: Report A = Tracking. Report B = Panic. Panic has priority over Tracking. Slider is changing the timer interval value.
I debugged my code and while it goes into the loop and cancels the timer task of the requested report, I still see those reports going through. Am I not cancelling the timer correctly? Please advice.
From the TimerTask.cancel javadoc:
... If the task has been scheduled for repeated execution, it will never run again. (If the task is running when this call occurs, the task will run to completion, but will never run again.) ...
So to begin with, calling cancel from a thread does not immediatly stop the Timer thread as you can see.
Also you are creating a new Timer each time in your screen:
trackSlider = new TimerTask()
Thus it might be possible that if you create several instances of your screen during the app running, several timers of the same type will be created.

Resources