Pass Outlook MailItem object from background thread to UI thread

Add-in Express™ Support Service
That's what is more important than anything else

Pass Outlook MailItem object from background thread to UI thread
 
tadams


Guest


Hi,

I am running a BackgroundWorker to search in the Draft folder for emails with specific custom tags applied, it then will scan the email calling an API in the process (which is why this is all being done in the background thread to not freeze the UI). If the API returns a specific value then I want to open that draft email and popup a message to the user in the main UI thread so that it blocks them doing anything else until they've clicked out of the message.

I plan to use Redemption in the background thread to safely process the folder and email, however I'm not sure the best/correct method to then pass the email reference to the UI thread. My current plan is to assign mailItem object to a variable that is passed into the BackgroundWorkerComplete event (which runs on the UI thread), however since this object is assigned to a Redemption RDOMail variable in the background thread, will I also need to use an RDOMail variable on the UI thread when using it?

Are there any better safe ways of doing this? For instance maybe I could retrieve the unique ID of the email in the background and pass this back to the UI thread, and then access the email using that.

I will obviously need to make sure to correctly release all the ComObjects at different stages too...

Thanks,
Tom
Posted 15 Jul, 2016 04:58:40 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Hello Tom,

You should regard all of the object models that Microsoft Office provides as thread-unsafe. For this reason, accessing an object model on a background thread isn't recommended. If you need to process a COM object on a background thread, you can retrieve the information from that COM object and process that info on the background thread (not the COM object itself). An alternative is processing the COM object on the main thread so that to leave enough time for the end user activity.

See also https://www.add-in-express.com/creating-addins-blog/2010/11/04/threads-managed-office-extensions/.


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jul, 2016 05:33:25 Top
tadams


Guest


Hi Andrei,

I have worked with objects in the background threads many times before using Redemption without any issues, are you saying this shouldn't be done at all or just that it is very risky and so care must be taken to do it properly?

Nevertheless I will try and change the overall order such that the draft email is retrieved and data extracted in the UI thread, then this is processed in the background thread. Hopefully searching for the email in the draft folder won't hold up Outlook.

Thanks,
Tom
Posted 15 Jul, 2016 05:45:52 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Tom,

Below I use citations from https://social.msdn.microsoft.com/Forums/vstudio/en-US/a4775ced-fa6d-44bf-b039-5bc72188e823/is-applicationclass-thread-safe?forum=vsto.

Technically, the object models *are* thread-safe:

#1.
Geoff explains why using a background thread doesn't make sense:
The Office object model is generally Single Threaded Apartment (STA). This means that COM will serialize all incoming calls. So to answer your question, the Word Application object is thread-safe because concurrency is simply prevented. What this means is that multi-threaded solutions involving Office may not offer any benefit over single threaded solutions if they attempt to make object model calls from multiple threads since the lack of concurrency support will result in threads being blocked much of the time. Typically, multi-threaded Office solutions are best implemented by making all object model calls from a single thread and then delegating the remaining (non-Office) work to background threads.


#2.
tadams writes:
I have worked with objects in the background threads many times before using Redemption without any issues


Here's what Geoff says:
You may well have been fairly lucky and not have seen the RPC_E_CALLRJECTED error to this point since the timing would have to be right to get it. However, you can reproduce it if you can display a modal dialog (such as File Open) while your solution is attempting to execute.


I don't think there's a really great way to handle that error; this is what allows me to call the object models thread-unsafe.

#3. Imagine two threads issuing two sets of COM calls dealing with a Word (Excel, PP, whatever) document. Let's assume the object model handles the calls with no problem. Still, if a COM call changes the state of inner objects, then the order in which the calls are issued makes a difference. In this sense, the object model can be called thread-unsafe, too.


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jul, 2016 08:45:40 Top
tadams


Guest


Hi Andrei,

I understand that in Outlook if accessing an object in the background then all that happens is the call to it is marshalled into the main thread, is this correct? This is useful because sometimes there is a long running process that can't be run in the main thread but requires data from Outlook items throughout, and so it is not practical to constantly try and jump in and out of a background process.

From what I have read it should be fine to access say the mailItem as long as I am only reading properties from it?

I have nonetheless changed my solution to the above to only access the mailItem in the main thread now so all should be fine.

Thanks,
Tom
Posted 15 Jul, 2016 09:05:05 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Tom,

tadams writes:
I understand that in Outlook if accessing an object in the background then all that happens is the call to it is marshalled into the main thread, is this correct? This is useful


Correct. Still, the RPC_E_CALLRJECTED error makes this way very shaky.

tadams writes:
From what I have read it should be fine to access say the mailItem as long as I am only reading properties from it?


You have every right to expect it *should* work this way. The reality is yet to explore. Be prepared it may be different for different Office versions.


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jul, 2016 09:23:38 Top
tadams


Guest


Hi Andrei,

Many thanks for the clarification and your help here, much appreciated as always! I have things working without accessing items from background thread now, just have a separate issue of trying to send a draft email using MailItem.Send() if the user has it open as an inline response (since I intercept and cancel the normal send event, do a quick bit of processing and then resend the email).

Since using that function on inline isn't possible it seems, I might have to force change the inspector window away from Drafts and then send it?

Regards,
Tom
Posted 15 Jul, 2016 10:04:08 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
You are welcome!

tadams writes:
I might have to force change the inspector window away from Drafts


to force the user?

Sorry, I won't be able to respond today. See you tomorrow.


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jul, 2016 10:11:24 Top