Redemption RDOFolderSynchronizer Not working on BackgroundWorker Thread - outlook-redemption

I am a long time Redemption coder, with several apps using Redemption on the background thread (but not using RDOFolderSynchronizer up to now).
I have a new rSession object created on the backgroundworker thread, to which I pass the MAPI Object.
RedemptionCode rCodeBW = new RedemptionCode();
rCodeBW.InitialiseRedemption(Globals.MapiObject, true);
On the background thread I am trying to use the RDOFolderSynchronizer but when I run it, I get an error when I try to retrieve the syncitems. The error is:
IMAPIFolder.OpenProperty(PR_CONTENTS_SYNCHRONIZER) returned MAPI_E_INTERFACE_NOT_SUPPORTED
Synchronization is only supported for the Exchange folders in the online mode.
If I run the same code in the main thread it works fine, so I 'think' the 'online mode' issue is not the direct reason it is failing.
The code I am using is:
var MAPI_NO_CACHE = 0x200;
var MAPI_BEST_ACCESS = 0x10;
RDOFolder2 rFolder2 = rSession.GetFolderFromID(entryID, storeID, MAPI_NO_CACHE ^ MAPI_BEST_ACCESS) as RDOFolder2;
RDOFolderSynchronizer synchronizer = rFolder2.ExchangeSynchronizer;
RDOSyncMessagesCollection syncItems = synchronizer.SyncItems(Globals.UserSettings.LastSyncDataEmailInbox);
Any suggestions gratefully received.

Yes, that interface has to be used on the same thread where the parent MAPI session (IMAPISession) is created. It is an ICS API limitation in Extended MAPI.

Related

How to restore runOn Scheduler used in previous operator?

Folks, is it possible to obtain currently used Scheduler within an operator?
The problem that I have is that Mono.fromFuture() is being executed on a native thread (AWS CRT Http Client in my case). As result all subsequent operators are also executed on that thread. And later code wants to obtain class loader context that is obviously null. I realize that I can call .publishOn(originalScheduler) after .fromFuture() but I don't know what scheduler is used to materialize Mono returned by my function.
Is there elegant way to deal with this?
fun myFunction(): Mono<String> {
return Mono.just("example")
.flatMap { value ->
Mono.fromFuture {
// invocation of 3rd party library that executes Future on the thread created in native code.
}
}
.map {
val resource = Thread.currentThread().getContextClassLoader().getResources("META-INF/services/blah_blah");
// NullPointerException because Thread.currentThread().getContextClassLoader() returns NULL
resource.asSequence().first().toString()
}
}
It is not possible, because there's no guarantee that there is a Scheduler at all.
The place where the subscription is made and the data starts flowing could simply be a Thread. There is no mechanism in Java that allows an external actor to submit a task to an arbitrary thread (you have to provide the Runnable at Thread construction).
So no, there's no way of "returning to the previous Scheduler".
Usually, this shouldn't be an issue at all. If your your code is reactive it should also be non-blocking and thus able to "share" whichever thread it currently runs on with other computations.
If your code is blocking, it should off-load the work to a blocking-compatible Scheduler anyway, which you should explicitly chose. Typically: publishOn(Schedulers.boundedElastic()). This is also true for CPU-intensive tasks btw.

System.MemberAccessException: Cannot create an instance of UserNotifications.UNNotificationTrigger because it is an abstract class

I am using the latest notification framework UNUserNotificationCenter for scheduling local notifications.
I am sharing some code snippets where I refer to trigger/access trigger.
Do not read this sequentially. It is just code snippets where I read or modift trigger
var trigger = UNCalendarNotificationTrigger.CreateTrigger(notification.ScheduledTime.DateTimeToNSDateComponents(), false);
trigger.DateComponents.Hour = trigger.DateComponents.Hour + 7;
var trigger = (UNCalendarNotificationTrigger)(notification.Trigger);
This works without any compilation error and the notification also worked. We have this code in the app store from past few months. Off late we are seeing a crash with the below message . I haven't referenced UNNotificationTrigger in my code. BTW this is xamarin IOS app.
System.MemberAccessException: Cannot create an instance of UserNotifications.UNNotificationTrigger because it is an abstract class
This is a problem in Xamarin.iOS that we are looking to fix.
What is going on is that the trigger vanishes or gets collected at some point, and it is later resurfaced, and the resurfacing does not know about the actual hidden concrete implementation for this, so you get the above message.
The best workaround for now is to keep a pointer to the trigger alive in managed code, thus ensuring that the resurfacing is never triggered.
We are tracking this here:
https://github.com/xamarin/xamarin-macios/issues/3935#issuecomment-381200652

Using Microsoft.bcl.async in PCL with Mono Droid?

I have a Portable Class Library (PCL) targeted at Profile158 (Windows Store, .NET 4.5, Silverlight 5, Windows Phone 8). I can easily work with methods that return a type of Task, and it all works as I would expect. Whenever I access the Result property, it finishes running the asynchronous code and returns the result.
However, if I use the async/await keywords in a method inside the PCL, I get a task back. However, when I attempt to access the Result property, it blocks and never returns.
Looking at the debug output window in Visual Studio in both cases I see the same text:
Thread started:
Thread started:
Loaded assembly: Mono.Security.dll [External]
Thread started:
Thread started:
So it appears as if the code is being run, but it never returns to the UI thread. Has anyone else tried to use a PCL with Microsoft.bcl.async in the PCL?
My Mono Droid project is targeted at Android 2.1.
Thanks,
-- John
Update:
Here is some additional information about the different scenarios. First, here is code that does work on Mono Droid when written in the UI code:
var task = request.GetResponseAsync();
string html = task.Result.GetResponseText();
I then created the following method in the PCL:
public async Task<string> Test()
{
IHttpResponse responce = await GetResponseAsync();
return responce.GetResponseText();
}
And call it with this code from the Mono UI code:
string html = request.Test().Result;
it never returns...
This is a classic deadlock scenario, as I describe on my blog.
By default, await will capture a "context" and use it to resume the async method. This "context" is the current SynchronizationContext unless it is null, in which case it's the current TaskScheduler.
So, you're calling an async method from a UI thread (which provides a SynchronizationContext), then blocking the UI thread by calling Result. The async method cannot finish because it is trying to finish on the UI thread, which is blocked.
To fix this, follow these guidelines:
Use async all the way down. Don't call Result or Wait on Tasks returned from async methods; use await instead.
Use ConfigureAwait(false) whenever possible in your library code.
You may also find my async/await intro helpful.

Call to CFReadStreamRead stops execution in thread

NB: The entire code base for this project is so large that posting any meaningful amount wold render this question too localised, I have tried to distil any code down to the bare-essentials. I'm not expecting anyone to solve my problems directly but I will up vote those answers I find helpful or intriguing.
This project uses a modified version of AudioStreamer to playback audio files that are saved to locally to the device (iPhone).
The stream is set up and scheduled on the current loop using this code (unaltered from the standard AudioStreamer project as far as I know):
CFStreamClientContext context = {0, self, NULL, NULL, NULL};
CFReadStreamSetClient(
stream,
kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
ASReadStreamCallBack,
&context);
CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
The ASReadStreamCallBack calls:
- (void)handleReadFromStream:(CFReadStreamRef)aStream
eventType:(CFStreamEventType)eventType
On the AudioStreamer object, this all works fine until the stream is read using this code:
BOOL hasBytes = NO; //Added for debugging
hasBytes = CFReadStreamHasBytesAvailable(stream);
length = CFReadStreamRead(stream, bytes, kAQDefaultBufSize);
hasBytes is YES but when CFReadStreamRead is called execution stops, the App does not crash it just stops exciting, any break points below the CFReadStreamRead call are not hit and ASReadStreamCallBack is not called again.
I am at a loss to what might cause this, my best guess is the thread is being terminated? But the hows and whys is why I'm asking SO.
Has anyone seen this behaviour before? How can I track it down and ideas on how I might solve it will be very much welcome!
Additional Info Requested via Comments
This is 100% repeatable
CFReadStreamHasBytesAvailable was added by me for debugging but removing it has no effect
First, I assume that CFReadStreamScheduleWithRunLoop() is running on the same thread as CFReadStreamRead()?
Is this thread processing its runloop? Failure to do this is my main suspicion. Do you have a call like CFRunLoopRun() or equivalent on this thread?
Typically there is no reason to spawn a separate thread for reading streams asynchronously, so I'm a little confused about your threading design. Is there really a background thread involved here? Also, typically CFReadStreamRead() would be in your client callback (when you receive the kCFStreamEventHasBytesAvailable event (which it appears to be in the linked code), but you're suggesting ASReadStreamCallBack is never called. How have you modified AudioStreamer?
It is possible that the stream pointer is just corrupt in some way. CFReadStreamRead should certainly not block if bytes are available (it certainly would never block for more than a few milliseconds for local files). Can you provide the code you use to create the stream?
Alternatively, CFReadStreams send messages asynchronously but it is possible (but not likely) that it's blocking because the runloop isn't being processed.
If you prefer, I've uploaded my AudioPlayer inspired by Matt's AudioStreamer hosted at https://code.google.com/p/audjustable/. It supports local files (as well as HTTP). I think it does what you wanted (stream files from more than just HTTP).

How to start a thread into a service in delphi 7, Windows XP?

We need to Start a thread into a service application we developed.
We did in the OnExecute event, and it failed, and later we did in the OnStart event, and it failed again. Maybe we have to do something else to start the thread.
The line of code we only have to type is MonitorThread.Start;
Where and how we can to start the thread??
Thanks.
On the face of it, starting a thread in a service is no different from starting a thread in any other kind of application. Simply instantiate the thread object and let it run. If you created the object in a suspended state, then call Start on it (or, in versions earlier than 2010, Resume).
MonitorThread := TMonitorThread.Create;
MonitorThread.Start; // or MonitorThread.Resume
If that doesn't work, then you need to take a closer look at exactly what doesn't work. Examine exception messages and return codes. Use the debugger to narrow things down.
If it's possible, I advise you to not create the thread suspended. Instead, just provide the object all the parameters it needs in its constructor. Let it initialize itself, and it will start running just before the constructor returns to the caller. No need for additional thread management outside the thread object.

Resources