Hang on Save in Excel

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

Hang on Save in Excel
 
Sean Devenish




Posts: 78
Joined: 2015-11-30
On isolated occasions, when a user of our product hits the save button in Excel, Excel shows the dialog "Microsoft Excel is waiting for another application to complete an OLE action' and hangs.

Is there anything that could be happening with our code or yours that could cause this behaviour? Given it is on rare occassions, it is impossible to replicate... but losing work when trying to save is not a good look for us! They have no other addins, use Office 365 in Windows Server 2012, terminal server environment.
Posted 15 Sep, 2016 19:44:59 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Sean,

Do you use the Excel object model (any Office object model) from a background thread?


Andrei Smolin
Add-in Express Team Leader
Posted 16 Sep, 2016 03:27:12 Top
Sean Devenish




Posts: 78
Joined: 2015-11-30
Hi Andrei,

we use c# async methods extensively, but none of them interact with the Excel (or any other Office object model), at least to our knowledge!
Posted 19 Sep, 2016 01:41:54 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Sean,

Do you use ConfigureAwait(false)?

Do you use DoEvents()?


Andrei Smolin
Add-in Express Team Leader
Posted 19 Sep, 2016 04:18:15 Top
Sean Devenish




Posts: 78
Joined: 2015-11-30
Yes, we use ConfigureAwait(false) extensively, but not DoEvents
Posted 19 Sep, 2016 04:40:42 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Sean Devenish writes:
Yes, we use ConfigureAwait(false) extensively


If an async method contains ConfigureAwait(false), this means the code executing after the async method returns is run on a background thread. If that code contains object model calls, you are in a trouble.

Additionally, this code may be executed in a different context. Consider this scenario. You have an event handler declared as async. In the code of the event handler you invoke an await operator with ConfigureAwait(false). Ignoring threading things for a moment, you have an asynchronous operation executing in the context that may differ from the context in which the operation was invoked originally. Context change may be almost anything: a window created/shown/hidden/destroyed, the selection changed, etc. I strongly believe using SendMessage/OnSendMessage and performing all activity while handling a custom message is far safer than using async/await.

Check https://msdn.microsoft.com/en-us/magazine/jj991977.aspx:

async Task MyMethodAsync()
{
// Code here runs in the original context.
await Task.Delay(1000);
// Code here runs in the original context.
await Task.Delay(1000).ConfigureAwait(
continueOnCapturedContext: false);
// Code here runs without the original
// context (in this case, on the thread pool).
}



Andrei Smolin
Add-in Express Team Leader
Posted 19 Sep, 2016 05:03:44 Top
Sean Devenish




Posts: 78
Joined: 2015-11-30
Thanks for this Andrei,

It will take some work to refactor all asynchronous operations to use SendMessage/OnSendMessage. If we removed all references to ConfigureAwait(false) from our asynchronous operations so that they continue on the captured context, will this likely help improve things meantime?
Posted 22 Sep, 2016 21:59:03 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Sean,

I believe such a change is correct. It should solve some problems in your add-in. I would find out whether ConfigureAwait(false) is responsible for the issue. You can add a number of debug messages to your code; use System.Diagnostics.Debug.WriteLine(). You collect the messages at run time using DebugView (see http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx).


Andrei Smolin
Add-in Express Team Leader
Posted 23 Sep, 2016 01:10:09 Top