This article explains how to create an agile version of a Windows Runtime delegate in C++/WinRT by wrapping the delegate in an agile_ref, with a promise of more details in part 2.
<p>Suppose you have some C++/WinRT code that receives a delegate from an outside source, and you might invoke that delegate from a potentially different COM context. However, the original delegate may not be agile. How can you make an agile version of that delegate?</p>
<p>The easy way is to wrap the delegate in an <code>agile_<wbr />ref</code>, and then resolve the <code>agile_<wbr />ref</code> back to a delegate when you want to invoke it.</p>
<pre>template<typename Delegate>
Delegate make_agile_delegate(Delegate const& d)
{
return [agile = winrt::agile_ref(d)](auto&&...args) {
return agile.get()(std::forward<decltype(args)>(args)...);
};
}
</pre>
<p>But if it were that easy, why would we call this article “part 1”?</p>
<p>More in part 2.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260720-00/?p=112545">Making an agile version of a Windows Runtime delegate in C++/WinRT, part 1</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
# Making an agile version of a Windows Runtime delegate in C++/WinRT, part 1 - The Old New Thing
Source: [https://devblogs.microsoft.com/oldnewthing/20260720-00?p=112545](https://devblogs.microsoft.com/oldnewthing/20260720-00?p=112545)
Suppose you have some C\+\+/WinRT code that receives a delegate from an outside source, and you might invoke that delegate from a potentially different COM context\. However, the original delegate may not be agile\. How can you make an agile version of that delegate?
The easy way is to wrap the delegate in an`agile\_ref`, and then resolve the`agile\_ref`back to a delegate when you want to invoke it\.
```
template<typename Delegate>
Delegate make_agile_delegate(Delegate const& d)
{
return [agile = winrt::agile_ref(d)](auto&&...args) {
return agile.get()(std::forward<decltype(args)>(args)...);
};
}
```
But if it were that easy, why would we call this article “part 1”?
More in part 2\.
### Category
### Topics
## Author

Raymond has been involved in the evolution of Windows for more than 30 years\. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie\-jeebies\. The Web site spawned a book, coincidentally also titled The Old New Thing \(Addison Wesley 2007\)\. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information\.
This article continues a series on implementing agile delegates in C++/WinRT, addressing the issue of destructing non-agile delegates in the correct context using a custom deleter and IContextCallback.
This blog post discusses handling Windows Runtime delegates that implement the INoMarshal interface in C++/WinRT, providing an agile delegate wrapper that checks the calling context to avoid marshaling errors.
This article discusses implementing an agile Windows Runtime delegate in C++/WinRT, focusing on using CoGetContextToken to compare context tokens for efficiency instead of comparing COM objects.
Raymond Chen explains why C++/WinRT does not allow multiple awaits on asynchronous operations like C#, JavaScript, and Python do, citing the lack of a standard library task type and the principle of not paying for unused functionality.
The article discusses a C++/WinRT pattern for caching the result of a Windows Runtime IAsyncOperation, including handling failures, so that multiple coroutines can share the cached result or exception.