|
6 | 6 |
|
7 | 7 | <introduction> |
8 | 8 | <para> |
9 | | - The openstack.net SDK is migrating to an asynchronous service model using the |
10 | | - <externalLink> |
11 | | - <linkText>Task-based Asynchronous Pattern (TAP)</linkText> |
12 | | - <linkAlternateText>Task-based Asynchronous Pattern (TAP) (Microsoft Developer Network)</linkAlternateText> |
13 | | - <linkUri>http://msdn.microsoft.com/en-us/library/hh873175.aspx</linkUri> |
14 | | - </externalLink> |
15 | | - for ongoing feature support. |
16 | | - This page contains information about several aspects of the asynchronous interfaces which could |
17 | | - result in some confusion during development. It also describes the inclusion of extension methods |
| 9 | + The openstack.net SDK is migrating to an asynchronous service model using the <token>TaskBasedAsync</token> |
| 10 | + for ongoing feature support. This page contains information about several aspects of the asynchronous interfaces |
| 11 | + which could result in some confusion during development. It also describes the inclusion of extension methods |
18 | 12 | that allow new product features to be used in code that is not allowed to make asynchronous API |
19 | 13 | calls. |
20 | 14 | </para> |
|
33 | 27 | <para> |
34 | 28 | The Task Parallel Library is used extensively by the implementation of this SDK. The library was |
35 | 29 | originally added as part of .NET 4, users still working with .NET 3.5 make use of the |
36 | | - <externalLink> |
37 | | - <linkText>Task Parallel Library for .NET 3.5</linkText> |
38 | | - <linkUri>http://www.nuget.org/packages/TaskParallelLibrary/</linkUri> |
39 | | - </externalLink> |
40 | | - package using NuGet. This package is automatically installed by NuGet when the SDK package is |
41 | | - added to a project targeting .NET 3.5. |
| 30 | + <token>TaskParallelLibrary35</token> package using NuGet. This package is automatically installed by NuGet |
| 31 | + when the SDK package is added to a project targeting .NET 3.5. |
42 | 32 | </para> |
43 | 33 | <para> |
44 | 34 | Language support varies by language. The following table shows the language features available |
|
182 | 172 | project file. |
183 | 173 | </para> |
184 | 174 | <code language="xml"><UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable></code> |
| 175 | + <alert class="important"> |
| 176 | + <para> |
| 177 | + While the <codeInline>UseHostCompilerIfAvailable</codeInline> setting allows Visual Studio 2010 to |
| 178 | + compile C# and Visual Basic projects using <token>AsyncAwait</token>, the editor itself does not |
| 179 | + recognize these keywords. As a result, some functionality including but not limited to IntelliSense may |
| 180 | + not function if this option is used. |
| 181 | + </para> |
| 182 | + </alert> |
185 | 183 | </content> |
186 | 184 | </section> |
187 | 185 | </sections> |
|
193 | 191 | <para> |
194 | 192 | Asynchronous methods are capable of throwing exceptions before creating a |
195 | 193 | <codeEntityReference>T:System.Threading.Tasks.Task</codeEntityReference> or during the asynchronous |
196 | | - execution of the task itself. The asynchronous service interfaces do not distinguish between these |
| 194 | + execution of the task itself. The documentation for asynchronous methods does not distinguish between these |
197 | 195 | two cases, allowing for any of the specified exceptions to be thrown in either manner. |
198 | 196 | </para> |
199 | | - <list class="bullet"> |
200 | | - <listItem> |
| 197 | + </content> |
| 198 | + |
| 199 | + <sections> |
| 200 | + <section> |
| 201 | + <title>Exceptions Prior to Task Creation</title> |
| 202 | + <content> |
201 | 203 | <para> |
202 | 204 | Exceptions thrown prior to the creation of the |
203 | 205 | <codeEntityReference>T:System.Threading.Tasks.Task</codeEntityReference> object representing the |
|
207 | 209 | <codeEntityReference>T:System.ArgumentNullException</codeEntityReference> or |
208 | 210 | <codeEntityReference>T:System.ArgumentException</codeEntityReference> to handle the exception. |
209 | 211 | </para> |
210 | | - </listItem> |
211 | | - <listItem> |
| 212 | + <code language="cs" region="ExceptionPriorToTaskCreation" source="..\Samples\CSharpCodeSamples\AsynchronousExceptionsExamples.cs"/> |
| 213 | + <code language="vb" region="ExceptionPriorToTaskCreation" source="..\Samples\VBCodeSamples\AsynchronousExceptionsExamples.vb"/> |
| 214 | + </content> |
| 215 | + </section> |
| 216 | + |
| 217 | + <section> |
| 218 | + <title>Exceptions During Task Execution</title> |
| 219 | + <content> |
212 | 220 | <para> |
213 | 221 | Exceptions thrown during the asynchronous execution of the task are wrapped in an |
214 | 222 | <codeEntityReference>T:System.AggregateException</codeEntityReference> object and returned by the |
|
220 | 228 | property within an exception handling block that includes a handler for |
221 | 229 | <codeEntityReference>T:System.AggregateException</codeEntityReference>. |
222 | 230 | </para> |
223 | | - </listItem> |
224 | | - </list> |
225 | | - </content> |
| 231 | + <para> |
| 232 | + This library additionally ensures that exceptions thrown by asynchronous operations are not wrapped in |
| 233 | + multiple layers of <codeEntityReference>T:System.AggregateException</codeEntityReference>. In other words, |
| 234 | + an <codeEntityReference>T:System.AggregateException</codeEntityReference> thrown during the asynchronous |
| 235 | + execution of a task will result in the |
| 236 | + <codeEntityReference>P:System.Threading.Tasks.Task.Exception</codeEntityReference> property returning an |
| 237 | + <codeEntityReference>T:System.AggregateException</codeEntityReference> with exactly one inner exception, |
| 238 | + which is the original <codeEntityReference>T:System.ArgumentException</codeEntityReference>. This |
| 239 | + guarantee simplifies the use of the API is languages that support <token>AsyncAwait</token>, since those |
| 240 | + operators automatically unwrap the first layer of |
| 241 | + <codeEntityReference>T:System.AggregateException</codeEntityReference>. |
| 242 | + </para> |
| 243 | + <code language="cs" region="ExceptionDuringTaskExecution" source="..\Samples\CSharpCodeSamples\AsynchronousExceptionsExamples.cs"/> |
| 244 | + <code language="vb" region="ExceptionDuringTaskExecution" source="..\Samples\VBCodeSamples\AsynchronousExceptionsExamples.vb"/> |
| 245 | + </content> |
| 246 | + </section> |
| 247 | + |
| 248 | + <section> |
| 249 | + <title>Consistent Exception Handling</title> |
| 250 | + <content> |
| 251 | + <para> |
| 252 | + Applications implementing specialized handling for exception which occur during asynchronous calls have |
| 253 | + multiple options available for consistent handling. The simplest solution, when available, involves using |
| 254 | + <token>AsyncAwait</token>. These operators automatically unwrap the first exception instance in the |
| 255 | + <codeEntityReference>P:System.AggregateException.InnerExceptions</codeEntityReference> collection of an |
| 256 | + <codeEntityReference>T:System.AggregateException</codeEntityReference>, resulting in behavior that appears |
| 257 | + to calling code as though the exception was directly thrown by the invoked method. The second method |
| 258 | + involves treating the original call as a continuation of another task, ensuring that all exceptions are |
| 259 | + presented as an <codeEntityReference>T:System.AggregateException</codeEntityReference> to the exception |
| 260 | + handling code. The following code shows the application of this strategy to an existing asynchronous call. |
| 261 | + Note that the <codeEntityReference>T:Rackspace.Threading.CompletedTask</codeEntityReference> class and |
| 262 | + <codeEntityReference>Overload:Rackspace.Threading.CoreTaskExtensions.Then</codeEntityReference> |
| 263 | + extension method are part of the <token>RackspaceThreadingLibrary</token> separately from this SDK. |
| 264 | + </para> |
| 265 | + <code language="cs" region="AsynchronousMethodAsContinuation" source="..\Samples\CSharpCodeSamples\AsynchronousExceptionsExamples.cs"/> |
| 266 | + <code language="vb" region="AsynchronousMethodAsContinuation" source="..\Samples\VBCodeSamples\AsynchronousExceptionsExamples.vb"/> |
| 267 | + <para> |
| 268 | + Code using the continuation strategy for consistent error handling may benefit from the use of the |
| 269 | + <codeEntityReference>Overload:Rackspace.Threading.CoreTaskExtensions.Catch</codeEntityReference> methods, |
| 270 | + which are also part of the <token>RackspaceThreadingLibrary</token>. This extension method behaves in a |
| 271 | + manner similar to <token>Await</token>, automatically unwrapping the first exception instance in the |
| 272 | + <codeEntityReference>P:System.AggregateException.InnerExceptions</codeEntityReference> collection |
| 273 | + of an <codeEntityReference>T:System.AggregateException</codeEntityReference> before invoking the |
| 274 | + continuation function which handles the exception. |
| 275 | + </para> |
| 276 | + </content> |
| 277 | + </section> |
| 278 | + </sections> |
226 | 279 | </section> |
227 | 280 |
|
228 | 281 | <section address="SynchronousExtensions"> |
|
0 commit comments