PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/V4/MVVM RI/MVVM.Questionnaires/Services/AsyncResult.cs

#
C# | 157 lines | 120 code | 21 blank | 16 comment | 15 complexity | e33053a5e0a1689591b9c2236eb2eae2 MD5 | raw file
  1. //===================================================================================
  2. // Microsoft patterns & practices
  3. // Composite Application Guidance for Windows Presentation Foundation and Silverlight
  4. //===================================================================================
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. // FITNESS FOR A PARTICULAR PURPOSE.
  10. //===================================================================================
  11. // The example companies, organizations, products, domain names,
  12. // e-mail addresses, logos, people, places, and events depicted
  13. // herein are fictitious. No association with any real company,
  14. // organization, product, domain name, email address, logo, person,
  15. // places, or events is intended or should be inferred.
  16. //===================================================================================
  17. using System;
  18. using System.Diagnostics.CodeAnalysis;
  19. using System.Threading;
  20. namespace MVVM.Questionnaires.Services
  21. {
  22. [SuppressMessage("Microsoft.Design", "CA1001",
  23. Justification = "Calling the End method, which is part of the contract of using an IAsyncResult, releases the IDisposable.")]
  24. public class AsyncResult<T> : IAsyncResult
  25. {
  26. private readonly object lockObject;
  27. private readonly AsyncCallback asyncCallback;
  28. private readonly object asyncState;
  29. private ManualResetEvent waitHandle;
  30. private T result;
  31. private Exception exception;
  32. private bool isCompleted;
  33. private bool completedSynchronously;
  34. private bool endCalled;
  35. public AsyncResult(AsyncCallback asyncCallback, object asyncState)
  36. {
  37. this.lockObject = new object();
  38. this.asyncCallback = asyncCallback;
  39. this.asyncState = asyncState;
  40. }
  41. public object AsyncState
  42. {
  43. get { return this.asyncState; }
  44. }
  45. public WaitHandle AsyncWaitHandle
  46. {
  47. get
  48. {
  49. lock (this.lockObject)
  50. {
  51. if (this.waitHandle == null)
  52. {
  53. this.waitHandle = new ManualResetEvent(this.IsCompleted);
  54. }
  55. }
  56. return this.waitHandle;
  57. }
  58. }
  59. public bool CompletedSynchronously
  60. {
  61. get { return this.completedSynchronously; }
  62. }
  63. public bool IsCompleted
  64. {
  65. get { return this.isCompleted; }
  66. }
  67. public T Result
  68. {
  69. get { return this.result; }
  70. }
  71. [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes",
  72. Justification = "Entry point to be used to implement End* methods.")]
  73. public static AsyncResult<T> End(IAsyncResult asyncResult)
  74. {
  75. var localResult = asyncResult as AsyncResult<T>;
  76. if (localResult == null)
  77. {
  78. throw new ArgumentNullException("asyncResult");
  79. }
  80. lock (localResult.lockObject)
  81. {
  82. if (localResult.endCalled)
  83. {
  84. throw new InvalidOperationException("End method already called");
  85. }
  86. localResult.endCalled = true;
  87. }
  88. if (!localResult.IsCompleted)
  89. {
  90. localResult.AsyncWaitHandle.WaitOne();
  91. }
  92. if (localResult.waitHandle != null)
  93. {
  94. localResult.waitHandle.Close();
  95. }
  96. if (localResult.exception != null)
  97. {
  98. throw localResult.exception;
  99. }
  100. return localResult;
  101. }
  102. public void SetComplete(T result, bool completedSynchronously)
  103. {
  104. this.result = result;
  105. this.DoSetComplete(completedSynchronously);
  106. }
  107. public void SetComplete(Exception e, bool completedSynchronously)
  108. {
  109. this.exception = e;
  110. this.DoSetComplete(completedSynchronously);
  111. }
  112. private void DoSetComplete(bool completedSynchronously)
  113. {
  114. if (completedSynchronously)
  115. {
  116. this.completedSynchronously = true;
  117. this.isCompleted = true;
  118. }
  119. else
  120. {
  121. lock (this.lockObject)
  122. {
  123. this.isCompleted = true;
  124. if (this.waitHandle != null)
  125. {
  126. this.waitHandle.Set();
  127. }
  128. }
  129. }
  130. if (this.asyncCallback != null)
  131. {
  132. this.asyncCallback(this);
  133. }
  134. }
  135. }
  136. }