source: BMXNET_RPMS_dotNET_UTILITIES-BMX/branch/IHS BMX Framework/IndianHealthService.BMXNet/Ado/DataTableFuture.cs@ 1146

Last change on this file since 1146 was 1146, checked in by Sam Habiel, 13 years ago

Initial Import of BMX4

File size: 10.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Data;
5using IndianHealthService.BMXNet.Services;
6using System.Windows.Forms;
7
8namespace IndianHealthService.BMXNet.Ado
9{
10 /// <summary>
11 /// DataTableFutures are created synchrounously when Async calls are made on a RemoteSession.
12 /// A DataTabelFuture is used to manage each async call and has a variety of methods to support
13 /// the relativelty long and dynamic lifecycle and an Async call.
14 /// </summary>
15 /// <remarks>
16 /// Beware that all return communications are not on the UI thread unless an InvokedControl
17 /// is specify.
18 /// </remarks>
19 public class DataTableFuture
20 {
21
22 /// <summary>
23 /// Triggered with the async returns, see DataTableFutureEventArgs to know if there
24 /// is a result waiting. It's very common to hook the Returned event after each Async call and
25 /// then unhook it when the Returned or Aborted calls return.
26 /// </summary>
27 public event EventHandler<DataTableFutureEventArgs> Returned;
28
29 /// <summary>
30 /// The async call was aborted by either the server or the client. It's very common to hook the Aborted event after each Async call and
31 /// then unhook it when the Returned or Aborted calls return.
32 /// </summary>
33 /// </summary>
34 public event EventHandler<DataTableFutureEventArgs> Aborted;
35
36 private Control _invokedControl = null;
37
38
39 /// If the InvokedControl is set to a valid Form or Control object (non-displosed), the
40 /// DataTabletFuture will trigger events on the UI thread using Invoke()
41 public Control InvokedControl
42 {
43 get { return _invokedControl; }
44 set { _invokedControl = value; }
45 }
46
47 private bool _isAutoFetchEnabled = true;
48
49 /// <summary>
50 /// If set to true the result will be fetched before the Returned event is called, otherwise
51 /// the Returned event will be triggered and the application code needs to call PostFetch() to retrieve
52 /// the result. True by default.
53 /// </summary>
54 public bool IsAutoFetchEnabled
55 {
56 get { return _isAutoFetchEnabled; }
57 set { _isAutoFetchEnabled = value; }
58 }
59
60 private Exception _errorException = null;
61
62
63 /// <summary>
64 /// Access to any exceptions that occur during Async call.
65 /// </summary>
66 public Exception ErrorException
67 {
68 get { return _errorException; }
69 set { _errorException = value; }
70 }
71
72 private int _resultId = 0;
73
74 internal int ResultId
75 {
76 get { return _resultId; }
77 set { _resultId = value; }
78 }
79
80 private String _resultKey = null;
81
82 protected String ResultKey
83 {
84 get { return _resultKey; }
85 set { _resultKey = value; }
86 }
87
88
89 private DataTable _result = null;
90
91 /// <summary>
92 /// The result table if any, or null.
93 /// </summary>
94 public DataTable Result
95 {
96 get { return _result; }
97 set { _result = value; }
98 }
99
100 private bool _wasCancelled = false;
101
102 /// <summary>
103 /// Answer true if canceled. It's common that a dialog would allow the user to cancel the
104 /// Async call and the Dialog that is holding on the the Future will cancel the Future. Cancelling
105 /// the Future does not stop the server-side processing but when the server returns nothing will happen.
106 /// </summary>
107 public bool WasCancelled
108 {
109 get { return _wasCancelled; }
110 set { _wasCancelled = value; }
111 }
112
113 private bool _hasTimedOut = false;
114
115 /// <summary>
116 /// Answer true if the Async call has timeed-out (a time-based version of Cancel)
117 /// </summary>
118 public bool HasTimedOut
119 {
120 get { return _hasTimedOut; }
121 set { _hasTimedOut = value; }
122 }
123
124 private bool _hasReturned = false;
125
126
127 /// <summary>
128 /// Answer true if the Async call has completed on the server and that a result is ready.
129 /// </summary>
130 public bool HasReturned
131 {
132 get { return _hasReturned; }
133 set
134 {
135 _hasReturned = value;
136 this.FutureTime = DateTime.Now;
137 }
138 }
139
140
141 private bool _hasData = false;
142
143 /// <summary>
144 /// Answer true if the data has been fetched from the server and is ready to be used by the application.
145 /// </summary>
146 public bool HasData
147 {
148 get { return _hasData; }
149 set { _hasData = value; }
150 }
151
152 private DateTime _presentTime = DateTime.Now;
153
154 /// <summary>
155 /// The time the Future was created.
156 /// </summary>
157 public DateTime PresentTime
158 {
159 get { return _presentTime; }
160 set { _presentTime = value; }
161 }
162
163 private DateTime? _futureTime = null;
164
165 /// <summary>
166 /// The time the async call returned (the future)
167 /// </summary>
168 public DateTime? FutureTime
169 {
170 get { return _futureTime; }
171 set { _futureTime = value; }
172 }
173
174 /// <summary>
175 /// How long in milliseconds the Async call took to complete.
176 /// </summary>
177 public double WaitTime
178 {
179 get
180 {
181 return ((this.FutureTime.HasValue ? this.FutureTime.Value : DateTime.Now) - this.PresentTime).TotalMilliseconds;
182 }
183 }
184
185 private int _maxWaitTime = 60 * 60 * 24;
186
187 /// <summary>
188 /// Number of seconds to wait for an async response before returning without a response.
189 /// </summary>
190 public int MaxWaitTime
191 {
192 get { return _maxWaitTime; }
193 set { _maxWaitTime = value; }
194 }
195
196 private BMXNetRemoteSession _session = null;
197
198 internal BMXNetRemoteSession Session
199 {
200 get { return _session; }
201 set { _session = value; }
202 }
203
204 /// <summary>
205 /// Method to cancel the Async call. This does not stop the server-side processing. The Aborted event
206 /// will be called immediately.
207 /// </summary>
208 public void Cancel()
209 {
210 this.WasCancelled = true;
211 this.Session.RemoveFromFutures(this);
212 this.TriggerAbortedEvent();
213 }
214
215 delegate void UiCall();
216
217 protected void TriggerAbortedEvent()
218 {
219 if (this.Aborted != null)
220 {
221 if (this.InvokedControl != null && this.InvokedControl.InvokeRequired)
222 {
223 this.InvokedControl.Invoke(new UiCall(UiTriggerAbortedEvent));
224 }
225 else
226 {
227 this.UiTriggerAbortedEvent();
228 }
229 }
230 }
231
232 private void UiTriggerAbortedEvent()
233 {
234 DataTableFutureEventArgs args = new DataTableFutureEventArgs();
235 args.Future = this;
236 this.Aborted(this, args);
237 }
238
239 protected void TriggerReturnedEvent()
240 {
241 if (this.Returned != null)
242 {
243 if (this.InvokedControl != null && this.InvokedControl.InvokeRequired)
244 {
245 this.InvokedControl.Invoke(new UiCall(UiTriggerReturnedEvent));
246 }
247 else
248 {
249 this.UiTriggerReturnedEvent();
250 }
251 }
252 }
253
254 private void UiTriggerReturnedEvent()
255 {
256 DataTableFutureEventArgs args = new DataTableFutureEventArgs();
257 args.Future = this;
258 this.Returned(this, args);
259 }
260
261
262 internal void FetchResults(BMXNetRemoteSession aSession)
263 {
264 if (!this.HasReturned || this.HasTimedOut || this.WasCancelled)
265 return;
266
267 try
268 {
269 this.Result = aSession.TableFromCommand("BMX ASYNC GET^" + this.ResultKey, this.ResultDataSet, this.ResultTableName, this.ResultAppContext);
270 this.HasData = true;
271 }
272 catch (Exception problem)
273 {
274 this.ErrorException = problem;
275 this.Cancel();
276 }
277 }
278
279 private BMXNetRemoteSession _fetchingSession = null;
280
281 internal BMXNetRemoteSession FetchingSession
282 {
283 get { return _fetchingSession; }
284 set { _fetchingSession = value; }
285 }
286
287 /// <summary>
288 /// If IsAutoFetchEnabled is false, then the results must be fetched synchrounously useding PostFetch().
289 /// Call PostFetch() once and check if HasData is true. If not true, there is was error related to the
290 /// async call.
291 /// </summary>
292 public void PostFetch()
293 {
294
295 this.FetchResults(this.FetchingSession);
296 }
297
298 internal void FutureHasReturned(BMXNetRemoteSession aSession, String resultsKey)
299 {
300 //TODO:If cancled, BMX ASYNC GET to clean cancelle ditem
301 if (this.HasReturned)
302 return;
303
304 this.ResultKey = resultsKey;
305 this.HasReturned = true;
306
307 if (!this.HasTimedOut && !this.WasCancelled)
308 {
309 if (this.IsAutoFetchEnabled)
310 {
311 this.FetchResults(aSession);
312 }
313 else
314 {
315 this.FetchingSession = aSession;
316 }
317 }
318
319 this.TriggerReturnedEvent();
320 }
321
322 private String _resultTableName = null;
323
324 public String ResultTableName
325 {
326 get { return _resultTableName; }
327 set { _resultTableName = value; }
328 }
329
330 private DataSet _resultDataSet = null;
331
332 /// <summary>
333 /// The data set the result data table is in.
334 /// </summary>
335 public DataSet ResultDataSet
336 {
337 get { return _resultDataSet; }
338 set { _resultDataSet = value; }
339 }
340
341 private String _resultAppContext = null;
342
343 /// <summary>
344 /// The AppContext that the async call was made with
345 /// </summary>
346 public String ResultAppContext
347 {
348 get { return _resultAppContext; }
349 set { _resultAppContext = value; }
350 }
351
352
353 }
354}
Note: See TracBrowser for help on using the repository browser.