Skip to content

Commit c8b1ab9

Browse files
committed
Create README.md
1 parent 6721160 commit c8b1ab9

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

Diff for: AsyncAwaitMacro/README.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
AsyncAwaitMacro sample
2+
---
3+
4+
Shows how the ExcelAsyncUtil.QueueAsMacro mechanism can be used to implement async macros with the C# async/await mechanism.
5+
6+
### Warning
7+
8+
This sample does not represent 'best practice'. It just explores how the C# async/await features interact with the Excel-DNA async mechanism, and with the Excel hosting environment.
9+
10+
Trying to run async macros as in this example will interfere with an interactive user busy with Excel:
11+
their undo stack and copy selection will get cleared at unexpected times, and any other add-ins or macros being run might be
12+
interleaved with the async code.
13+
14+
#### `ExcelAsyncTask`
15+
16+
The sample includes a helper class called `ExcelAsyncTask` with a single `Run` method.
17+
In turn, this starts the `Task` with a TaskScheduler which just enqueues `Task`s to run in the macro context,
18+
ensuring that the async/await continuations are again scheduled in a macro context.
19+
20+
```c#
21+
22+
public static void MacroToRunSlowWork()
23+
{
24+
// Starts running SlowWork in a context where async/await will return to the macro context on the main Excel thread.
25+
ExcelTaskAsync.Run(SlowWork);
26+
}
27+
28+
static async Task SlowWork()
29+
{
30+
// All the code here, before and after the awaits, will run on the main thread in a macro context
31+
// (where C API calls and the COM object model is safe to access).
32+
await SomeWorkAsync();
33+
Application.Range["A1"].Value = "abc;
34+
await OtherWorkAsync();
35+
Application.Range["A2"].Value = "xyz;
36+
}
37+
38+
```
39+
40+
41+
#### `ExcelSynchronizationContext`
42+
43+
The first implementation I attempted was run the async/await code in a context where `SynchronizationContext.Current` was set to an `ExcelSynchronizationContext`.
44+
45+
There is a problem I don't yet understand when trying to use a `SynchronizationContext` in Excel-DNA.
46+
Somehow the `SynchronizationContext.Current` is cleared in the SyncWindow or macro running process.
47+
I have found references to `WindowsFormsSynchronizationContext.AutoInstall` causing trouble, but could not see how that applies in our case.
48+
49+
It could be that the unmanaged -> managed transition interferes with the thread-based context that stores the SynchronizationContext.Current.
50+
As an alternative, we use the TaskScheduler-based approach.
51+

0 commit comments

Comments
 (0)