Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System / compmod / system / componentmodel / AsyncOperation.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="AsyncOperation.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.ComponentModel
8 {
9     using System.Security.Permissions;
10     using System.Threading;
11     
12     [HostProtection(SharedState = true)]
13     public sealed class AsyncOperation
14     {
15         private SynchronizationContext syncContext;
16         private object userSuppliedState; 
17         private bool alreadyCompleted;
18
19         /// <summary>
20         ///     Constructor. Protected to avoid unwitting usage - AsyncOperation objects
21         ///     are typically created by AsyncOperationManager calling CreateOperation.
22         /// </summary>
23         private AsyncOperation(object userSuppliedState, SynchronizationContext syncContext)
24         {
25             this.userSuppliedState = userSuppliedState;
26             this.syncContext = syncContext;
27             this.alreadyCompleted = false;
28             this.syncContext.OperationStarted();
29         }
30
31         /// <summary>
32         ///     Destructor. Guarantees that [....] context will always get notified of completion.
33         /// </summary>
34         ~AsyncOperation()
35         {
36             if (!alreadyCompleted && syncContext != null)
37             {
38                 syncContext.OperationCompleted();
39             }
40         }
41
42         public object UserSuppliedState
43         {
44             get { return userSuppliedState; }
45         }
46
47         /// <include file='doc\AsyncOperation.uex' path='docs/doc[@for="AsyncOperation.SynchronizationContext"]/*' />
48         public SynchronizationContext SynchronizationContext
49         {
50             get
51             {
52                 return syncContext;
53             }
54         }
55
56         public void Post(SendOrPostCallback d, object arg)
57         {
58             VerifyNotCompleted();
59             VerifyDelegateNotNull(d);
60             syncContext.Post(d, arg);
61         }
62
63         public void PostOperationCompleted(SendOrPostCallback d, object arg)
64         {
65             Post(d, arg);
66             OperationCompletedCore();
67         }
68
69         public void OperationCompleted()
70         {
71             VerifyNotCompleted();
72             OperationCompletedCore();
73         }
74
75         private void OperationCompletedCore()
76         {
77             try
78             {
79                 syncContext.OperationCompleted();
80             }
81             finally
82             {
83                 alreadyCompleted = true;
84                 GC.SuppressFinalize(this);
85             }
86         }
87
88         private void VerifyNotCompleted()
89         {
90             if (alreadyCompleted)
91             {
92                 throw new InvalidOperationException(SR.GetString(SR.Async_OperationAlreadyCompleted));
93             }
94         }
95
96         private void VerifyDelegateNotNull(SendOrPostCallback d)
97         {
98             if (d == null)
99             {
100                 throw new ArgumentNullException(SR.GetString(SR.Async_NullDelegate), "d");
101             }
102         }
103
104         /// <summary>
105         ///     Only for use by AsyncOperationManager to create new AsyncOperation objects
106         /// </summary>
107         internal static AsyncOperation CreateOperation(object userSuppliedState, SynchronizationContext syncContext)
108         {
109             AsyncOperation newOp = new AsyncOperation(userSuppliedState, syncContext); 
110             return newOp;
111         }
112     }
113 }
114