Skip to content
This repository
Browse code

Windows Azure Storage Client 2.0.2 Hotfix

  • Loading branch information...
commit f9c38e9276eceef18626dd8bcda08da32eb79516 1 parent be17b8c
Serdar Ozler authored November 27, 2012

Showing 49 changed files with 1,904 additions and 337 deletions. Show diff stats Hide diff stats

  1. 2  microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Constants.cs
  2. 6  microsoft-azure-api/Services/Storage/Lib/Common/Table/DynamicTableEntity.cs
  3. 70  microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityProperty.cs
  4. 156  microsoft-azure-api/Services/Storage/Lib/Common/Table/TableEntity.cs
  5. 2  microsoft-azure-api/Services/Storage/Lib/DotNet40/Properties/AssemblyInfo.cs
  6. 8  microsoft-azure-api/Services/Storage/Lib/DotNet40/Table/CloudTable.cs
  7. 16  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobReadStream.cs
  8. 93  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobWriteStream.cs
  9. 3  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobClient.cs
  10. 10  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobContainer.cs
  11. 16  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlockBlob.cs
  12. 19  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudPageBlob.cs
  13. 6  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/Executor.cs
  14. 2  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableExecutor.cs
  15. 6  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncStreamCopier.cs
  16. 20  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageCommandAsyncResult.cs
  17. 8  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueue.cs
  18. 2  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceContext.cs
  19. 15  microsoft-azure-api/Services/Storage/Lib/RT/Properties/AssemblyInfo.cs
  20. 2  microsoft-azure-api/Services/Storage/Lib/RTTable/Properties/AssemblyInfo.cs
  21. 2  microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Properties/AssemblyInfo.cs
  22. 169  microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/Entities/ComplexEntity.cs
  23. 34  microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableBatchOperationTest.cs
  24. 132  microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableOperationUnitTests.cs
  25. 59  microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableQueryGenericTests.cs
  26. 18  microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableQueryTests.cs
  27. 4  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobManglerUnitTests.cs
  28. 8  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobReadStreamTest.cs
  29. 92  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobClientTest.cs
  30. 69  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobContainerTest.cs
  31. 11  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobDirectoryTest.cs
  32. 212  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlockBlobTest.cs
  33. 187  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudPageBlobTest.cs
  34. 6  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/MD5FlagsTest.cs
  35. 53  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/SASTests.cs
  36. 20  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueTest.cs
  37. 215  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/DataServices/TableEntityUnitTests.cs
  38. 8  microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/DataServices/TableServiceContextUnitTests.cs
  39. 8  microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobReadStreamTest.cs
  40. 5  microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobContainerTest.cs
  41. 21  microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobDirectoryTest.cs
  42. 95  microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlockBlobTest.cs
  43. 85  microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudPageBlobTest.cs
  44. 53  microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/SASTests.cs
  45. 2  microsoft-azure-api/Services/Storage/Test/Unit/RT/Properties/AssemblyInfo.cs
  46. 169  microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/Entities/ComplexEntity.cs
  47. 12  microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableBatchOperationTest.cs
  48. 12  microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableOperationUnitTests.cs
  49. 18  microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryTests.cs
2  microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Constants.cs
@@ -605,7 +605,7 @@ internal class HeaderConstants
605 605
             /// <summary>
606 606
             /// Specifies the value to use for UserAgent header.
607 607
             /// </summary>
608  
-            public const string UserAgentProductVersion = "2.0.1";
  608
+            public const string UserAgentProductVersion = "2.0.2";
609 609
 
610 610
             /// <summary>
611 611
             /// Master Windows Azure Storage header prefix.
6  microsoft-azure-api/Services/Storage/Lib/Common/Table/DynamicTableEntity.cs
@@ -40,7 +40,7 @@ public DynamicTableEntity()
40 40
         /// <param name="partitionKey">The partition key value for the entity.</param>
41 41
         /// <param name="rowKey">The row key value for the entity.</param>
42 42
         public DynamicTableEntity(string partitionKey, string rowKey)
43  
-            : this(partitionKey, rowKey, DateTime.MinValue, null /* timestamp */, new Dictionary<string, EntityProperty>())
  43
+            : this(partitionKey, rowKey, DateTimeOffset.MinValue, null /* timestamp */, new Dictionary<string, EntityProperty>())
44 44
         {
45 45
         }
46 46
 
@@ -53,7 +53,7 @@ public DynamicTableEntity(string partitionKey, string rowKey)
53 53
         /// <param name="properties">The entity's properties, indexed by property name.</param>
54 54
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is consistent with IDictionary<> itself.")]
55 55
         public DynamicTableEntity(string partitionKey, string rowKey, string etag, IDictionary<string, EntityProperty> properties)
56  
-            : this(partitionKey, rowKey, DateTime.MinValue, etag, properties)
  56
+            : this(partitionKey, rowKey, DateTimeOffset.MinValue, etag, properties)
57 57
         {
58 58
         }
59 59
 
@@ -65,7 +65,7 @@ public DynamicTableEntity(string partitionKey, string rowKey, string etag, IDict
65 65
         /// <param name="timestamp">The timestamp for this entity as returned by Windows Azure.</param>
66 66
         /// <param name="etag">The entity's current ETag; set to null to ignore the ETag during subsequent update operations.</param>
67 67
         /// <param name="properties">An <see cref="IDictionary{TKey,TElement}"/> containg a map of <see cref="string"/> property names to <see cref="EntityProperty"/> data typed values to store in the new <see cref="DynamicTableEntity"/>.</param>
68  
-        internal DynamicTableEntity(string partitionKey, string rowKey, DateTime timestamp, string etag, IDictionary<string, EntityProperty> properties)
  68
+        internal DynamicTableEntity(string partitionKey, string rowKey, DateTimeOffset timestamp, string etag, IDictionary<string, EntityProperty> properties)
69 69
         {
70 70
             CommonUtils.AssertNotNull("partitionKey", partitionKey);
71 71
             CommonUtils.AssertNotNull("rowKey", rowKey);
70  microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityProperty.cs
@@ -81,7 +81,7 @@ public static EntityProperty GeneratePropertyForDateTimeOffset(DateTimeOffset? i
81 81
         /// </summary>
82 82
         /// <param name="input">The value for the new <see cref="EntityProperty"/>.</param>
83 83
         /// <returns>A new <see cref="EntityProperty"/> of the <see cref="Boolean"/> type.</returns>
84  
-        public static EntityProperty GeneratePropertyForBool(bool input)
  84
+        public static EntityProperty GeneratePropertyForBool(bool? input)
85 85
         {
86 86
             return new EntityProperty(input);
87 87
         }
@@ -91,7 +91,7 @@ public static EntityProperty GeneratePropertyForBool(bool input)
91 91
         /// </summary>
92 92
         /// <param name="input">The value for the new <see cref="EntityProperty"/>.</param>
93 93
         /// <returns>A new <see cref="EntityProperty"/> of the <see cref="Double"/> type.</returns>
94  
-        public static EntityProperty GeneratePropertyForDouble(double input)
  94
+        public static EntityProperty GeneratePropertyForDouble(double? input)
95 95
         {
96 96
             return new EntityProperty(input);
97 97
         }
@@ -101,7 +101,7 @@ public static EntityProperty GeneratePropertyForDouble(double input)
101 101
         /// </summary>
102 102
         /// <param name="input">The value for the new <see cref="EntityProperty"/>.</param>
103 103
         /// <returns>A new <see cref="EntityProperty"/> of the <see cref="Guid"/> type.</returns>
104  
-        public static EntityProperty GeneratePropertyForGuid(Guid input)
  104
+        public static EntityProperty GeneratePropertyForGuid(Guid? input)
105 105
         {
106 106
             return new EntityProperty(input);
107 107
         }
@@ -111,7 +111,7 @@ public static EntityProperty GeneratePropertyForGuid(Guid input)
111 111
         /// </summary>
112 112
         /// <param name="input">The value for the new <see cref="EntityProperty"/>.</param>
113 113
         /// <returns>A new <see cref="EntityProperty"/> of the <see cref="Int32"/> type.</returns>
114  
-        public static EntityProperty GeneratePropertyForInt(int input)
  114
+        public static EntityProperty GeneratePropertyForInt(int? input)
115 115
         {
116 116
             return new EntityProperty(input);
117 117
         }
@@ -121,7 +121,7 @@ public static EntityProperty GeneratePropertyForInt(int input)
121 121
         /// </summary>
122 122
         /// <param name="input">The value for the new <see cref="EntityProperty"/>.</param>
123 123
         /// <returns>A new <see cref="EntityProperty"/> of the <see cref="Int64"/> type.</returns>
124  
-        public static EntityProperty GeneratePropertyForLong(long input)
  124
+        public static EntityProperty GeneratePropertyForLong(long? input)
125 125
         {
126 126
             return new EntityProperty(input);
127 127
         }
@@ -166,9 +166,10 @@ public static EntityProperty GeneratePropertyForString(string input)
166 166
 #else
167 167
         public
168 168
 #endif
169  
- EntityProperty(bool input)
  169
+ EntityProperty(bool? input)
170 170
             : this(EdmType.Boolean)
171 171
         {
  172
+            this.IsNull = !input.HasValue;
172 173
             this.PropertyAsObject = input;
173 174
         }
174 175
 
@@ -224,9 +225,10 @@ public static EntityProperty GeneratePropertyForString(string input)
224 225
 #else
225 226
         public
226 227
 #endif
227  
- EntityProperty(double input)
  228
+ EntityProperty(double? input)
228 229
             : this(EdmType.Double)
229 230
         {
  231
+            this.IsNull = !input.HasValue;
230 232
             this.PropertyAsObject = input;
231 233
         }
232 234
 
@@ -240,9 +242,10 @@ public static EntityProperty GeneratePropertyForString(string input)
240 242
 #else
241 243
         public
242 244
 #endif
243  
- EntityProperty(Guid input)
  245
+ EntityProperty(Guid? input)
244 246
             : this(EdmType.Guid)
245 247
         {
  248
+            this.IsNull = !input.HasValue;
246 249
             this.PropertyAsObject = input;
247 250
         }
248 251
 
@@ -256,9 +259,10 @@ public static EntityProperty GeneratePropertyForString(string input)
256 259
 #else
257 260
         public
258 261
 #endif
259  
- EntityProperty(int input)
  262
+ EntityProperty(int? input)
260 263
             : this(EdmType.Int32)
261 264
         {
  265
+            this.IsNull = !input.HasValue;
262 266
             this.PropertyAsObject = input;
263 267
         }
264 268
 
@@ -272,9 +276,10 @@ public static EntityProperty GeneratePropertyForString(string input)
272 276
 #else
273 277
         public
274 278
 #endif
275  
- EntityProperty(long input)
  279
+ EntityProperty(long? input)
276 280
             : this(EdmType.Int64)
277 281
         {
  282
+            this.IsNull = !input.HasValue;
278 283
             this.PropertyAsObject = input;
279 284
         }
280 285
 
@@ -334,18 +339,19 @@ public byte[] BinaryValue
334 339
         /// An exception will be thrown if you attempt to set this property to anything other than an <see cref="Boolean"/> Object.
335 340
         /// </summary>
336 341
         /// <value>The <see cref="Boolean"/> value of this <see cref="EntityProperty"/> object.</value>
337  
-        public bool BooleanValue
  342
+        public bool? BooleanValue
338 343
         {
339 344
             get
340 345
             {
341 346
                 this.EnforceType(EdmType.Boolean);
342  
-                return (bool)this.PropertyAsObject;
  347
+                return (bool?)this.PropertyAsObject;
343 348
             }
344 349
 
345 350
             set
346 351
             {
347 352
                 this.EnforceType(EdmType.Boolean);
348 353
                 this.PropertyAsObject = value;
  354
+                this.IsNull = value.HasValue;
349 355
             }
350 356
         }
351 357
 
@@ -399,18 +405,19 @@ public bool BooleanValue
399 405
         /// An exception will be thrown if you attempt to set this property to anything other than a <see cref="Double"/> object.
400 406
         /// </summary>
401 407
         /// <value>The <see cref="Double"/> value of this <see cref="EntityProperty"/> object.</value>
402  
-        public double DoubleValue
  408
+        public double? DoubleValue
403 409
         {
404 410
             get
405 411
             {
406 412
                 this.EnforceType(EdmType.Double);
407  
-                return (double)this.PropertyAsObject;
  413
+                return (double?)this.PropertyAsObject;
408 414
             }
409 415
 
410 416
             set
411 417
             {
412 418
                 this.EnforceType(EdmType.Double);
413 419
                 this.PropertyAsObject = value;
  420
+                this.IsNull = value.HasValue;
414 421
             }
415 422
         }
416 423
 
@@ -419,18 +426,19 @@ public double DoubleValue
419 426
         /// An exception will be thrown if you attempt to set this property to anything other than a <see cref="Guid"/> object.
420 427
         /// </summary>
421 428
         /// <value>The <see cref="Guid"/> value of this <see cref="EntityProperty"/> object.</value>
422  
-        public Guid GuidValue
  429
+        public Guid? GuidValue
423 430
         {
424 431
             get
425 432
             {
426 433
                 this.EnforceType(EdmType.Guid);
427  
-                return (Guid)this.PropertyAsObject;
  434
+                return (Guid?)this.PropertyAsObject;
428 435
             }
429 436
 
430 437
             set
431 438
             {
432 439
                 this.EnforceType(EdmType.Guid);
433 440
                 this.PropertyAsObject = value;
  441
+                this.IsNull = value.HasValue;
434 442
             }
435 443
         }
436 444
 
@@ -439,18 +447,19 @@ public Guid GuidValue
439 447
         /// An exception will be thrown if you attempt to set this property to anything other than an <see cref="Int32"/> Object.
440 448
         /// </summary>
441 449
         /// <value>The <see cref="Int32"/> value of this <see cref="EntityProperty"/> object.</value>
442  
-        public int Int32Value
  450
+        public int? Int32Value
443 451
         {
444 452
             get
445 453
             {
446 454
                 this.EnforceType(EdmType.Int32);
447  
-                return (int)this.PropertyAsObject;
  455
+                return (int?)this.PropertyAsObject;
448 456
             }
449 457
 
450 458
             set
451 459
             {
452 460
                 this.EnforceType(EdmType.Int32);
453 461
                 this.PropertyAsObject = value;
  462
+                this.IsNull = value.HasValue;
454 463
             }
455 464
         }
456 465
 
@@ -459,18 +468,19 @@ public int Int32Value
459 468
         /// An exception will be thrown if you attempt to set this property to anything other than an <see cref="Int64"/> Object.
460 469
         /// </summary>
461 470
         /// <value>The <see cref="Int64"/> value of this <see cref="EntityProperty"/> object.</value>
462  
-        public long Int64Value
  471
+        public long? Int64Value
463 472
         {
464 473
             get
465 474
             {
466 475
                 this.EnforceType(EdmType.Int64);
467  
-                return (long)this.PropertyAsObject;
  476
+                return (long?)this.PropertyAsObject;
468 477
             }
469 478
 
470 479
             set
471 480
             {
472 481
                 this.EnforceType(EdmType.Int64);
473 482
                 this.PropertyAsObject = value;
  483
+                this.IsNull = value.HasValue;
474 484
             }
475 485
         }
476 486
 
@@ -564,6 +574,10 @@ internal static EntityProperty CreateEntityPropertyFromObject(object value, bool
564 574
             {
565 575
                 return new EntityProperty((bool)value);
566 576
             }
  577
+            else if (value is bool?)
  578
+            {
  579
+                return new EntityProperty((bool?)value);
  580
+            }
567 581
             else if (value is DateTime)
568 582
             {
569 583
                 return new EntityProperty((DateTime)value);
@@ -584,6 +598,14 @@ internal static EntityProperty CreateEntityPropertyFromObject(object value, bool
584 598
             {
585 599
                 return new EntityProperty((double)value);
586 600
             }
  601
+            else if (value is double?)
  602
+            {
  603
+                return new EntityProperty((double?)value);
  604
+            }
  605
+            else if (value is Guid?)
  606
+            {
  607
+                return new EntityProperty((Guid?)value);
  608
+            }
587 609
             else if (value is Guid)
588 610
             {
589 611
                 return new EntityProperty((Guid)value);
@@ -592,10 +614,18 @@ internal static EntityProperty CreateEntityPropertyFromObject(object value, bool
592 614
             {
593 615
                 return new EntityProperty((int)value);
594 616
             }
  617
+            else if (value is int?)
  618
+            {
  619
+                return new EntityProperty((int?)value);
  620
+            }
595 621
             else if (value is long)
596 622
             {
597 623
                 return new EntityProperty((long)value);
598 624
             }
  625
+            else if (value is long?)
  626
+            {
  627
+                return new EntityProperty((long?)value);
  628
+            }
599 629
             else if (value == null)
600 630
             {
601 631
                 return new EntityProperty((string)null);
156  microsoft-azure-api/Services/Storage/Lib/Common/Table/TableEntity.cs
@@ -119,84 +119,86 @@ public virtual void ReadEntity(IDictionary<string, EntityProperty> properties, O
119 119
                 {
120 120
                     property.SetValue(this, null, null);
121 121
                 }
122  
-
123  
-                switch (entityProperty.PropertyType)
  122
+                else
124 123
                 {
125  
-                    case EdmType.String:
126  
-                        if (property.PropertyType != typeof(string) && property.PropertyType != typeof(String))
127  
-                        {
128  
-                            continue;
129  
-                        }
130  
-
131  
-                        property.SetValue(this, entityProperty.StringValue, null);
132  
-                        break;
133  
-                    case EdmType.Binary:
134  
-                        if (property.PropertyType != typeof(byte[]))
135  
-                        {
136  
-                            continue;
137  
-                        }
138  
-
139  
-                        property.SetValue(this, entityProperty.BinaryValue, null);
140  
-                        break;
141  
-                    case EdmType.Boolean:
142  
-                        if (property.PropertyType != typeof(bool) && property.PropertyType != typeof(Boolean))
143  
-                        {
144  
-                            continue;
145  
-                        }
146  
-
147  
-                        property.SetValue(this, entityProperty.BooleanValue, null);
148  
-                        break;
149  
-                    case EdmType.DateTime:
150  
-                        if (property.PropertyType == typeof(DateTime))
151  
-                        {
152  
-                            property.SetValue(this, entityProperty.DateTimeOffsetValue.Value.UtcDateTime, null);
153  
-                        }
154  
-                        else if (property.PropertyType == typeof(DateTime?))
155  
-                        {
156  
-                            property.SetValue(this, entityProperty.DateTimeOffsetValue.HasValue ? entityProperty.DateTimeOffsetValue.Value.UtcDateTime : (DateTime?)null, null);
157  
-                        }
158  
-                        else if (property.PropertyType == typeof(DateTimeOffset))
159  
-                        {
160  
-                            property.SetValue(this, entityProperty.DateTimeOffsetValue.Value, null);
161  
-                        }
162  
-                        else if (property.PropertyType == typeof(DateTimeOffset?))
163  
-                        {
164  
-                            property.SetValue(this, entityProperty.DateTimeOffsetValue, null);
165  
-                        }
166  
-
167  
-                        break;
168  
-                    case EdmType.Double:
169  
-                        if (property.PropertyType != typeof(double) && property.PropertyType != typeof(Double))
170  
-                        {
171  
-                            continue;
172  
-                        }
173  
-
174  
-                        property.SetValue(this, entityProperty.DoubleValue, null);
175  
-                        break;
176  
-                    case EdmType.Guid:
177  
-                        if (property.PropertyType != typeof(Guid))
178  
-                        {
179  
-                            continue;
180  
-                        }
181  
-
182  
-                        property.SetValue(this, entityProperty.GuidValue, null);
183  
-                        break;
184  
-                    case EdmType.Int32:
185  
-                        if (property.PropertyType != typeof(int) && property.PropertyType != typeof(Int32))
186  
-                        {
187  
-                            continue;
188  
-                        }
189  
-
190  
-                        property.SetValue(this, entityProperty.Int32Value, null);
191  
-                        break;
192  
-                    case EdmType.Int64:
193  
-                        if (property.PropertyType != typeof(long) && property.PropertyType != typeof(Int64))
194  
-                        {
195  
-                            continue;
196  
-                        }
197  
-
198  
-                        property.SetValue(this, entityProperty.Int64Value, null);
199  
-                        break;
  124
+                    switch (entityProperty.PropertyType)
  125
+                    {
  126
+                        case EdmType.String:
  127
+                            if (property.PropertyType != typeof(string) && property.PropertyType != typeof(String))
  128
+                            {
  129
+                                continue;
  130
+                            }
  131
+
  132
+                            property.SetValue(this, entityProperty.StringValue, null);
  133
+                            break;
  134
+                        case EdmType.Binary:
  135
+                            if (property.PropertyType != typeof(byte[]))
  136
+                            {
  137
+                                continue;
  138
+                            }
  139
+
  140
+                            property.SetValue(this, entityProperty.BinaryValue, null);
  141
+                            break;
  142
+                        case EdmType.Boolean:
  143
+                            if (property.PropertyType != typeof(bool) && property.PropertyType != typeof(Boolean))
  144
+                            {
  145
+                                continue;
  146
+                            }
  147
+
  148
+                            property.SetValue(this, entityProperty.BooleanValue, null);
  149
+                            break;
  150
+                        case EdmType.DateTime:
  151
+                            if (property.PropertyType == typeof(DateTime))
  152
+                            {
  153
+                                property.SetValue(this, entityProperty.DateTimeOffsetValue.Value.UtcDateTime, null);
  154
+                            }
  155
+                            else if (property.PropertyType == typeof(DateTime?))
  156
+                            {
  157
+                                property.SetValue(this, entityProperty.DateTimeOffsetValue.HasValue ? entityProperty.DateTimeOffsetValue.Value.UtcDateTime : (DateTime?)null, null);
  158
+                            }
  159
+                            else if (property.PropertyType == typeof(DateTimeOffset))
  160
+                            {
  161
+                                property.SetValue(this, entityProperty.DateTimeOffsetValue.Value, null);
  162
+                            }
  163
+                            else if (property.PropertyType == typeof(DateTimeOffset?))
  164
+                            {
  165
+                                property.SetValue(this, entityProperty.DateTimeOffsetValue, null);
  166
+                            }
  167
+
  168
+                            break;
  169
+                        case EdmType.Double:
  170
+                            if (property.PropertyType != typeof(double) && property.PropertyType != typeof(Double))
  171
+                            {
  172
+                                continue;
  173
+                            }
  174
+
  175
+                            property.SetValue(this, entityProperty.DoubleValue, null);
  176
+                            break;
  177
+                        case EdmType.Guid:
  178
+                            if (property.PropertyType != typeof(Guid) && property.PropertyType != typeof(Guid?))
  179
+                            {
  180
+                                continue;
  181
+                            }
  182
+
  183
+                            property.SetValue(this, entityProperty.GuidValue, null);
  184
+                            break;
  185
+                        case EdmType.Int32:
  186
+                            if (property.PropertyType != typeof(int) && property.PropertyType != typeof(Int32))
  187
+                            {
  188
+                                continue;
  189
+                            }
  190
+
  191
+                            property.SetValue(this, entityProperty.Int32Value, null);
  192
+                            break;
  193
+                        case EdmType.Int64:
  194
+                            if (property.PropertyType != typeof(long) && property.PropertyType != typeof(Int64))
  195
+                            {
  196
+                                continue;
  197
+                            }
  198
+
  199
+                            property.SetValue(this, entityProperty.Int64Value, null);
  200
+                            break;
  201
+                    }
200 202
                 }
201 203
             }
202 204
         }
2  microsoft-azure-api/Services/Storage/Lib/DotNet40/Properties/AssemblyInfo.cs
@@ -36,7 +36,7 @@
36 36
 // by using the '*' as shown below:
37 37
 // [assembly: AssemblyVersion("1.0.*")]
38 38
 [assembly: AssemblyVersion("2.0.0.0")]
39  
-[assembly: AssemblyFileVersion("2.0.1.0")]
  39
+[assembly: AssemblyFileVersion("2.0.2.0")]
40 40
 
41 41
 #if SIGNED
42 42
 [assembly: InternalsVisibleTo(
8  microsoft-azure-api/Services/Storage/Lib/DotNet40/Table/CloudTable.cs
@@ -519,7 +519,7 @@ private void CreateIfNotExistHandler(IAsyncResult asyncResult)
519 519
             lock (chainedResult.CancellationLockerObject)
520 520
             {
521 521
                 chainedResult.CancelDelegate = null;
522  
-                chainedResult.CompletedSynchronously = chainedResult.CompletedSynchronously & asyncResult.CompletedSynchronously;
  522
+                chainedResult.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously);
523 523
 
524 524
                 try
525 525
                 {
@@ -538,7 +538,7 @@ private void CreateIfNotExistHandler(IAsyncResult asyncResult)
538 538
                              createRes =>
539 539
                              {
540 540
                                  chainedResult.CancelDelegate = null;
541  
-                                 chainedResult.CompletedSynchronously = chainedResult.CompletedSynchronously & createRes.CompletedSynchronously;
  541
+                                 chainedResult.UpdateCompletedSynchronously(chainedResult.CompletedSynchronously);
542 542
 
543 543
                                  try
544 544
                                  {
@@ -763,7 +763,7 @@ private void DeleteIfExistsHandler(IAsyncResult asyncResult)
763 763
             lock (chainedResult.CancellationLockerObject)
764 764
             {
765 765
                 chainedResult.CancelDelegate = null;
766  
-                chainedResult.CompletedSynchronously = chainedResult.CompletedSynchronously & asyncResult.CompletedSynchronously;
  766
+                chainedResult.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously);
767 767
 
768 768
                 try
769 769
                 {
@@ -782,7 +782,7 @@ private void DeleteIfExistsHandler(IAsyncResult asyncResult)
782 782
                             (deleteRes) =>
783 783
                             {
784 784
                                 chainedResult.CancelDelegate = null;
785  
-                                chainedResult.CompletedSynchronously = chainedResult.CompletedSynchronously & deleteRes.CompletedSynchronously;
  785
+                                chainedResult.UpdateCompletedSynchronously(deleteRes.CompletedSynchronously);
786 786
 
787 787
                                 try
788 788
                                 {
16  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobReadStream.cs
@@ -97,10 +97,7 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy
97 97
             CommonUtils.AssertInBounds("offset", offset, 0, buffer.Length);
98 98
             CommonUtils.AssertInBounds("count", count, 0, buffer.Length - offset);
99 99
 
100  
-            ChainedAsyncResult<int> chainedResult = new ChainedAsyncResult<int>(callback, state)
101  
-            {
102  
-                CompletedSynchronously = true,
103  
-            };
  100
+            ChainedAsyncResult<int> chainedResult = new ChainedAsyncResult<int>(callback, state);
104 101
 
105 102
             if (this.lastException != null)
106 103
             {
@@ -116,6 +113,8 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy
116 113
                         this.operationContext,
117 114
                         ar =>
118 115
                         {
  116
+                            chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  117
+
119 118
                             try
120 119
                             {
121 120
                                 this.blob.EndFetchAttributes(ar);
@@ -123,14 +122,11 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy
123 122
                             catch (Exception e)
124 123
                             {
125 124
                                 this.lastException = e;
126  
-                                chainedResult.CompletedSynchronously &= ar.CompletedSynchronously;
127 125
                                 chainedResult.OnComplete(this.lastException);
128 126
                                 return;
129 127
                             }
130 128
 
131 129
                             this.LockToETag();
132  
-
133  
-                            chainedResult.CompletedSynchronously &= ar.CompletedSynchronously;
134 130
                             this.isLengthAvailable = true;
135 131
 
136 132
                             if (string.IsNullOrEmpty(this.blob.Properties.ContentMD5))
@@ -240,7 +236,7 @@ private void DispatchRead(ChainedAsyncResult<int> chainedResult, byte[] buffer,
240 236
                                         this.parallelOperationSemaphore.Release();
241 237
 
242 238
                                         // End the async result
243  
-                                        chainedResult.CompletedSynchronously &= ar.CompletedSynchronously;
  239
+                                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
244 240
                                         chainedResult.OnComplete(this.lastException);
245 241
                                     },
246 242
                                     null /* state */);
@@ -258,7 +254,7 @@ private void DispatchRead(ChainedAsyncResult<int> chainedResult, byte[] buffer,
258 254
                                 this.parallelOperationSemaphore.Release();
259 255
 
260 256
                                 // End the async result
261  
-                                chainedResult.CompletedSynchronously &= calledSynchronously;
  257
+                                chainedResult.UpdateCompletedSynchronously(calledSynchronously);
262 258
                                 chainedResult.OnComplete(this.lastException);
263 259
                             }
264 260
                         }
@@ -267,7 +263,7 @@ private void DispatchRead(ChainedAsyncResult<int> chainedResult, byte[] buffer,
267 263
                             this.lastException = e;
268 264
 
269 265
                             // End the async result
270  
-                            chainedResult.CompletedSynchronously &= calledSynchronously;
  266
+                            chainedResult.UpdateCompletedSynchronously(calledSynchronously);
271 267
                             chainedResult.OnComplete(this.lastException);
272 268
                         }
273 269
                     });
93  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobWriteStream.cs
@@ -146,7 +146,6 @@ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, As
146 146
 
147 147
             if (!dispatched)
148 148
             {
149  
-                chainedResult.CompletedSynchronously = true;
150 149
                 chainedResult.OnComplete(this.lastException);
151 150
             }
152 151
 
@@ -277,6 +276,7 @@ private void DispatchWrite(ChainedAsyncResult<NullType> asyncResult)
277 276
         /// </summary>
278 277
         /// <param name="blockData">Data to be uploaded</param>
279 278
         /// <param name="blockId">Block ID</param>
  279
+        /// <param name="blockMD5">MD5 hash of the data to be uploaded</param>
280 280
         /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
281 281
         private void WriteBlock(Stream blockData, string blockId, string blockMD5, ChainedAsyncResult<NullType> asyncResult)
282 282
         {
@@ -285,6 +285,11 @@ private void WriteBlock(Stream blockData, string blockId, string blockMD5, Chain
285 285
 
286 286
             bool completedSynchronously = this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
287 287
                 {
  288
+                    if (asyncResult != null)
  289
+                    {
  290
+                        asyncResult.UpdateCompletedSynchronously(calledSynchronously);
  291
+                    }
  292
+
288 293
                     try
289 294
                     {
290 295
                         this.blockBlob.BeginPutBlock(
@@ -305,28 +310,21 @@ private void WriteBlock(Stream blockData, string blockId, string blockMD5, Chain
305 310
                                     this.lastException = e;
306 311
                                 }
307 312
 
308  
-                                try
  313
+                                // This must be called before calling the user's callback
  314
+                                // in case the callback is blocking.
  315
+                                if (Interlocked.Decrement(ref this.pendingWrites) == 0)
309 316
                                 {
310  
-                                    if (!calledSynchronously && (asyncResult != null))
311  
-                                    {
312  
-                                        // End the async result
313  
-                                        asyncResult.CompletedSynchronously = ar.CompletedSynchronously;
314  
-                                        asyncResult.OnComplete(this.lastException);
315  
-                                    }
  317
+                                    this.noPendingWritesEvent.Set();
316 318
                                 }
317  
-                                catch (Exception)
318  
-                                {
319  
-                                    // If user's callback throws an exception, we want to
320  
-                                    // ignore and continue.
321  
-                                }
322  
-                                finally
323  
-                                {
324  
-                                    if (Interlocked.Decrement(ref this.pendingWrites) == 0)
325  
-                                    {
326  
-                                        this.noPendingWritesEvent.Set();
327  
-                                    }
328 319
 
329  
-                                    this.parallelOperationSemaphore.Release();
  320
+                                this.parallelOperationSemaphore.Release();
  321
+
  322
+                                // Do not try-catch this portion, as we are done anyway.
  323
+                                // We should let the user handle the exception.
  324
+                                if (!calledSynchronously && (asyncResult != null))
  325
+                                {
  326
+                                    // End the async result
  327
+                                    asyncResult.OnComplete(this.lastException);
330 328
                                 }
331 329
                             },
332 330
                             null /* state */);
@@ -336,14 +334,15 @@ private void WriteBlock(Stream blockData, string blockId, string blockMD5, Chain
336 334
                         this.lastException = e;
337 335
 
338 336
                         // End the async result
339  
-                        asyncResult.CompletedSynchronously = calledSynchronously;
340  
-                        asyncResult.OnComplete(e);
  337
+                        if (asyncResult != null)
  338
+                        {
  339
+                            asyncResult.OnComplete(e);
  340
+                        }
341 341
                     }
342 342
                 });
343 343
 
344  
-            if (completedSynchronously && asyncResult != null)
  344
+            if (completedSynchronously && (asyncResult != null))
345 345
             {
346  
-                asyncResult.CompletedSynchronously = true;
347 346
                 asyncResult.OnComplete();
348 347
             }
349 348
         }
@@ -354,6 +353,7 @@ private void WriteBlock(Stream blockData, string blockId, string blockMD5, Chain
354 353
         /// </summary>
355 354
         /// <param name="pageData">Data to be uploaded</param>
356 355
         /// <param name="offset">Offset within the page blob</param>
  356
+        /// <param name="contentMD5">MD5 hash of the data to be uploaded</param>
357 357
         /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
358 358
         private void WritePages(Stream pageData, long offset, string contentMD5, ChainedAsyncResult<NullType> asyncResult)
359 359
         {
@@ -362,6 +362,11 @@ private void WritePages(Stream pageData, long offset, string contentMD5, Chained
362 362
 
363 363
             bool completedSynchronously = this.parallelOperationSemaphore.WaitAsync(calledSynchronously =>
364 364
                 {
  365
+                    if (asyncResult != null)
  366
+                    {
  367
+                        asyncResult.UpdateCompletedSynchronously(calledSynchronously);
  368
+                    }
  369
+
365 370
                     try
366 371
                     {
367 372
                         this.pageBlob.BeginWritePages(
@@ -382,28 +387,21 @@ private void WritePages(Stream pageData, long offset, string contentMD5, Chained
382 387
                                     this.lastException = e;
383 388
                                 }
384 389
 
385  
-                                try
  390
+                                // This must be called before calling the user's callback
  391
+                                // in case the callback is blocking.
  392
+                                if (Interlocked.Decrement(ref this.pendingWrites) == 0)
386 393
                                 {
387  
-                                    if (!calledSynchronously && (asyncResult != null))
388  
-                                    {
389  
-                                        // End the async result
390  
-                                        asyncResult.CompletedSynchronously = ar.CompletedSynchronously;
391  
-                                        asyncResult.OnComplete(this.lastException);
392  
-                                    }
  394
+                                    this.noPendingWritesEvent.Set();
393 395
                                 }
394  
-                                catch (Exception)
395  
-                                {
396  
-                                    // If user's callback throws an exception, we want to
397  
-                                    // ignore and continue.
398  
-                                }
399  
-                                finally
400  
-                                {
401  
-                                    if (Interlocked.Decrement(ref this.pendingWrites) == 0)
402  
-                                    {
403  
-                                        this.noPendingWritesEvent.Set();
404  
-                                    }
405 396
 
406  
-                                    this.parallelOperationSemaphore.Release();
  397
+                                this.parallelOperationSemaphore.Release();
  398
+
  399
+                                // Do not try-catch this portion, as we are done anyway.
  400
+                                // We should let the user handle the exception.
  401
+                                if (!calledSynchronously && (asyncResult != null))
  402
+                                {
  403
+                                    // End the async result
  404
+                                    asyncResult.OnComplete(this.lastException);
407 405
                                 }
408 406
                             },
409 407
                             null /* state */);
@@ -413,14 +411,15 @@ private void WritePages(Stream pageData, long offset, string contentMD5, Chained
413 411
                         this.lastException = e;
414 412
 
415 413
                         // End the async result
416  
-                        asyncResult.CompletedSynchronously = calledSynchronously;
417  
-                        asyncResult.OnComplete(e);
  414
+                        if (asyncResult != null)
  415
+                        {
  416
+                            asyncResult.OnComplete(e);
  417
+                        }
418 418
                     }
419 419
                 });
420 420
 
421  
-            if (completedSynchronously && asyncResult != null)
  421
+            if (completedSynchronously && (asyncResult != null))
422 422
             {
423  
-                asyncResult.CompletedSynchronously = true;
424 423
                 asyncResult.OnComplete();
425 424
             }
426 425
         }
3  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobClient.cs
@@ -301,6 +301,8 @@ public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, bool useFl
301 301
                 operationContext,
302 302
                 ar =>
303 303
                 {
  304
+                    result.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  305
+
304 306
                     try
305 307
                     {
306 308
                         result.Result = container.EndListBlobsSegmented(ar);
@@ -312,6 +314,7 @@ public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, bool useFl
312 314
                     }
313 315
                 },
314 316
                 null /* state */);
  317
+
315 318
             result.CancelDelegate = asyncResult.Cancel;
316 319
             return result;
317 320
         }
10  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobContainer.cs
@@ -153,7 +153,6 @@ public ICancellableAsyncResult BeginCreateIfNotExists(BlobRequestOptions options
153 153
             {
154 154
                 RequestOptions = modifiedOptions,
155 155
                 OperationContext = operationContext,
156  
-                CompletedSynchronously = true,
157 156
             };
158 157
             this.CreateIfNotExistsHandler(options, operationContext, chainedResult);
159 158
             return chainedResult;
@@ -168,7 +167,7 @@ private void CreateIfNotExistsHandler(BlobRequestOptions options, OperationConte
168 167
                     operationContext,
169 168
                     existsResult =>
170 169
                     {
171  
-                        chainedResult.CompletedSynchronously &= existsResult.CompletedSynchronously;
  170
+                        chainedResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously);
172 171
                         lock (chainedResult.CancellationLockerObject)
173 172
                         {
174 173
                             chainedResult.CancelDelegate = null;
@@ -187,7 +186,7 @@ private void CreateIfNotExistsHandler(BlobRequestOptions options, OperationConte
187 186
                                     operationContext,
188 187
                                     createResult =>
189 188
                                     {
190  
-                                        chainedResult.CompletedSynchronously &= createResult.CompletedSynchronously;
  189
+                                        chainedResult.UpdateCompletedSynchronously(createResult.CompletedSynchronously);
191 190
                                         chainedResult.CancelDelegate = null;
192 191
                                         try
193 192
                                         {
@@ -371,7 +370,6 @@ public ICancellableAsyncResult BeginDeleteIfExists(AccessCondition accessConditi
371 370
             {
372 371
                 RequestOptions = modifiedOptions,
373 372
                 OperationContext = operationContext,
374  
-                CompletedSynchronously = true,
375 373
             };
376 374
             this.DeleteIfExistsHandler(accessCondition, options, operationContext, chainedResult);
377 375
             return chainedResult;
@@ -386,7 +384,7 @@ private void DeleteIfExistsHandler(AccessCondition accessCondition, BlobRequestO
386 384
                     operationContext,
387 385
                     existsResult =>
388 386
                     {
389  
-                        chainedResult.CompletedSynchronously &= existsResult.CompletedSynchronously;
  387
+                        chainedResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously);
390 388
                         lock (chainedResult.CancellationLockerObject)
391 389
                         {
392 390
                             chainedResult.CancelDelegate = null;
@@ -406,7 +404,7 @@ private void DeleteIfExistsHandler(AccessCondition accessCondition, BlobRequestO
406 404
                                     operationContext,
407 405
                                     deleteResult =>
408 406
                                     {
409  
-                                        chainedResult.CompletedSynchronously &= deleteResult.CompletedSynchronously;
  407
+                                        chainedResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously);
410 408
                                         chainedResult.CancelDelegate = null;
411 409
                                         try
412 410
                                         {
16  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlockBlob.cs
@@ -86,7 +86,6 @@ public ICancellableAsyncResult BeginOpenWrite(AccessCondition accessCondition, B
86 86
         {
87 87
             ChainedAsyncResult<Stream> chainedResult = new ChainedAsyncResult<Stream>(callback, state)
88 88
             {
89  
-                CompletedSynchronously = true,
90 89
                 Result = this.OpenWrite(accessCondition, options, operationContext),
91 90
             };
92 91
             chainedResult.OnComplete();
@@ -212,6 +211,8 @@ public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondit
212 211
                         streamCopyState,
213 212
                         completedState =>
214 213
                         {
  214
+                            chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);
  215
+
215 216
                             try
216 217
                             {
217 218
                                 lock (chainedResult.CancellationLockerObject)
@@ -253,6 +254,8 @@ public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondit
253 254
                     null /* streamCopyState */,
254 255
                     completedState =>
255 256
                     {
  257
+                        chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);
  258
+
256 259
                         try
257 260
                         {
258 261
                             blobStream.Close();
@@ -276,6 +279,8 @@ private void UploadFromStreamHandler(Stream source, string contentMD5, AccessCon
276 279
                 operationContext,
277 280
                 ar =>
278 281
                 {
  282
+                    chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  283
+
279 284
                     try
280 285
                     {
281 286
                         Executor.EndExecuteAsync<NullType>(ar);
@@ -786,7 +791,6 @@ public ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteS
786 791
             {
787 792
                 RequestOptions = modifiedOptions,
788 793
                 OperationContext = operationContext,
789  
-                CompletedSynchronously = true,
790 794
             };
791 795
             this.DeleteIfExistsHandler(deleteSnapshotsOption, accessCondition, options, operationContext, chainedResult);
792 796
             return chainedResult;
@@ -801,7 +805,7 @@ private void DeleteIfExistsHandler(DeleteSnapshotsOption deleteSnapshotsOption,
801 805
                     operationContext,
802 806
                     existsResult =>
803 807
                     {
804  
-                        chainedResult.CompletedSynchronously &= existsResult.CompletedSynchronously;
  808
+                        chainedResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously);
805 809
                         lock (chainedResult.CancellationLockerObject)
806 810
                         {
807 811
                             chainedResult.CancelDelegate = null;
@@ -822,7 +826,7 @@ private void DeleteIfExistsHandler(DeleteSnapshotsOption deleteSnapshotsOption,
822 826
                                     operationContext,
823 827
                                     deleteResult =>
824 828
                                     {
825  
-                                        chainedResult.CompletedSynchronously &= deleteResult.CompletedSynchronously;
  829
+                                        chainedResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously);
826 830
                                         chainedResult.CancelDelegate = null;
827 831
                                         try
828 832
                                         {
@@ -1399,6 +1403,8 @@ public ICancellableAsyncResult BeginPutBlock(string blockId, Stream blockData, s
1399 1403
                     streamCopyState,
1400 1404
                     _ =>
1401 1405
                     {
  1406
+                        chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);
  1407
+
1402 1408
                         if (executionState.ExceptionRef != null)
1403 1409
                         {
1404 1410
                             chainedResult.OnComplete(executionState.ExceptionRef);
@@ -1436,6 +1442,8 @@ private void PutBlockHandler(string blockId, Stream blockData, string contentMD5
1436 1442
                     operationContext,
1437 1443
                     ar =>
1438 1444
                     {
  1445
+                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  1446
+
1439 1447
                         try
1440 1448
                         {
1441 1449
                             Executor.EndExecuteAsync<NullType>(ar);
19  microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudPageBlob.cs
@@ -114,10 +114,11 @@ public ICancellableAsyncResult BeginOpenWrite(long? size, AccessCondition access
114 114
                     operationContext,
115 115
                     ar =>
116 116
                     {
  117
+                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  118
+
117 119
                         try
118 120
                         {
119 121
                             this.EndCreate(ar);
120  
-                            chainedResult.CompletedSynchronously = ar.CompletedSynchronously;
121 122
                             chainedResult.Result = new BlobWriteStream(this, size.Value, accessCondition, modifiedOptions, operationContext);
122 123
                             chainedResult.OnComplete();
123 124
                         }
@@ -136,10 +137,11 @@ public ICancellableAsyncResult BeginOpenWrite(long? size, AccessCondition access
136 137
                     operationContext,
137 138
                     ar =>
138 139
                     {
  140
+                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  141
+
139 142
                         try
140 143
                         {
141 144
                             this.EndFetchAttributes(ar);
142  
-                            chainedResult.CompletedSynchronously = ar.CompletedSynchronously;
143 145
                             chainedResult.Result = new BlobWriteStream(this, this.Properties.Length, accessCondition, modifiedOptions, operationContext);
144 146
                             chainedResult.OnComplete();
145 147
                         }
@@ -381,6 +383,8 @@ public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondit
381 383
                     operationContext,
382 384
                     ar =>
383 385
                     {
  386
+                        chainedResult.UpdateCompletedSynchronously(ar.CompletedSynchronously);
  387
+
384 388
                         lock (chainedResult.CancellationLockerObject)
385 389
                         {
386 390
                             chainedResult.CancelDelegate = null;
@@ -398,6 +402,8 @@ public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondit
398 402
                                     null /* streamCopyState */,
399 403
                                     completedState =>
400 404
                                     {
  405
+                                        chainedResult.UpdateCompletedSynchronously(executionState.CompletedSynchronously);
  406
+
401 407
                                         try
402 408
                                         {
403 409
                                             blobStream.Close();
@@ -992,7 +998,6 @@ public ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteS