CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
CancellableViewModel.cs
Go to the documentation of this file.
1#if !XAMARIN && !WINDOWS_UWP
2//-----------------------------------------------------------------------
3// <copyright file="CancellableViewModel.cs" company="Marimer LLC">
4// Copyright (c) Marimer LLC. All rights reserved.
5// Website: https://cslanet.com
6// </copyright>
7// <summary>Base class used to create CancellableViewModel objects,</summary>
8//-----------------------------------------------------------------------
9using System;
10using System.Collections.Generic;
11
12using Csla.Reflection;
13
14namespace Csla.Xaml
15{
20 [Obsolete("Use ViewModelBase.RefreshAsync", false)]
21 public abstract class CancellableViewModel<T> : ViewModel<T>
22 {
23 private CslaOperation<T> _lastOperation;
24 private Action<CslaOperation<T>> _nextOperationExecutor = null;
25
29 {
31 }
32
37 public bool IsConcurentRefreshesAllowed { get; set; }
38
47 [Obsolete("Use RefreshAsync", false)]
48 protected new void BeginRefresh(Action<EventHandler<DataPortalResult<T>>> factoryMethod)
49 {
50 ExecuteOperation(operation => operation.Execute(factoryMethod));
51 }
52
59 [Obsolete("Use RefreshAsync", false)]
60 protected override void BeginRefresh(string factoryMethod, params object[] factoryParameters)
61 {
62 ExecuteOperation(operation => operation.Execute(factoryMethod, factoryParameters));
63 }
64
68 [Obsolete("Use RefreshAsync", false)]
69 public virtual void CancelRefresh()
70 {
71 _nextOperationExecutor = null;
72 if (_lastOperation != null)
73 {
74 _lastOperation.Cancel();
75 }
76 IsBusy = false;
77 Model = default(T);
78 Error = null;
79 }
80
81 private void ExecuteOperation(Action<CslaOperation<T>> operationExecutor)
82 {
83 try
84 {
85 if (_lastOperation != null)
86 _lastOperation.Cancel();
87
88 if (!IsConcurentRefreshesAllowed && _lastOperation != null)
89 {
90 _nextOperationExecutor = operationExecutor;
91 return;
92 }
93
94 Error = null;
95 IsBusy = true;
96
97 _lastOperation = new CslaOperation<T>(QueryCompleted);
98 operationExecutor(_lastOperation);
99 }
100 catch (Exception ex)
101 {
102 Error = ex;
103 IsBusy = false;
104 }
105 }
106
107 private void QueryCompleted(DataPortalResult<T> result, bool isCanceled)
108 {
109 _lastOperation = null;
110
111 if (!IsConcurentRefreshesAllowed && _nextOperationExecutor != null)
112 {
113 var executor = _nextOperationExecutor;
114 _nextOperationExecutor = null;
115 ExecuteOperation(executor);
116 return;
117 }
118
119 if (isCanceled) return;
120
121 try
122 {
123 if (result.Error == null)
124 {
125 OnRefreshing(result.Object);
126 Model = result.Object;
127 }
128 else
129 Error = result.Error;
130 OnRefreshed();
131 }
132 finally
133 {
134 IsBusy = false;
135 }
136 }
137 }
138
139 internal class CslaOperation<T>
140 {
141 private readonly Action<DataPortalResult<T>, bool> _onCompletedQuery;
142 private bool _isCanceled;
143
144 public CslaOperation(Action<DataPortalResult<T>, bool> onCompletedQuery)
145 {
146 if (onCompletedQuery == null) throw new ArgumentNullException("onCompletedQuery");
147
148 _onCompletedQuery = onCompletedQuery;
149 }
150
151 public void Cancel()
152 {
153 _isCanceled = true;
154 }
155
156 public void Execute(Action<EventHandler<DataPortalResult<T>>> factoryMethod)
157 {
158 EventHandler<DataPortalResult<T>> handler = (sender, result) => _onCompletedQuery(result, _isCanceled);
159 factoryMethod(handler);
160 }
161
162 public void Execute(string factoryMethod, params object[] factoryParameters)
163 {
164 var parameters = new List<object>(factoryParameters) { CreateHandler() };
165 MethodCaller.CallFactoryMethod(typeof(T), factoryMethod, parameters.ToArray());
166 }
167
168 private Delegate CreateHandler()
169 {
170 var args = typeof(DataPortalResult<>).MakeGenericType(typeof(T));
171 System.Reflection.MethodInfo method = MethodCaller.GetNonPublicMethod(GetType(), "QueryCompleted");
172 Delegate handler = Delegate.CreateDelegate(typeof(EventHandler<>).MakeGenericType(args), this, method);
173 return handler;
174 }
175
176 private void QueryCompleted(object sender, EventArgs e)
177 {
178 DataPortalResult<T> result = (DataPortalResult<T>)e;
179 _onCompletedQuery(result, _isCanceled);
180 }
181 }
182}
183#endif
DataPortalResult defines the results of DataPortal operation.
ViewModel without multithreading (concurrency) bugs.
bool IsConcurentRefreshesAllowed
Allows more than one refresh operations in one time.
new void BeginRefresh(Action< EventHandler< DataPortalResult< T > > > factoryMethod)
Creates or retrieves a new instance of the Model by invoking a static factory method.
virtual void CancelRefresh()
Cancel refresh operation.
override void BeginRefresh(string factoryMethod, params object[] factoryParameters)
Creates or retrieves a new instance of the Model by invoking a static factory method.
T Model
Gets or sets the Model object.
virtual void OnRefreshed()
Method called after a refresh operation has completed.
bool IsBusy
Gets a value indicating whether this object is executing an asynchronous process.
virtual void OnRefreshing(T model)
Method called after a refresh operation has completed and before the model is updated.
Exception Error
Gets the Error object corresponding to the last asynchronous operation.
Base class used to create ViewModel objects, with pre-existing verbs for use by InvokeMethod or Invok...
@ Execute
Execute operation.