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.
BackgroundWorker.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="BackgroundWorker.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Wraps a System.ComponentModel.BackgroundWorker and transfers ApplicationContext.User, ClientContest, GlobalContext, CurrentCulture and CurrentUICulture to background thread.</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.ComponentModel;
10using System.Globalization;
11using System.Threading;
12
13namespace Csla.Threading
14{
19 public class BackgroundWorker : System.ComponentModel.Component
20 {
21 private readonly System.ComponentModel.BackgroundWorker _myWorker = new System.ComponentModel.BackgroundWorker();
26 {
27 _myWorker.DoWork += InternalDoWork;
28 _myWorker.RunWorkerCompleted += InternalRunWorkerCompleted;
29 _myWorker.ProgressChanged += InternalProgressChanged;
30 }
31
32 // overridden event handler to be invoked by this class
33 private DoWorkEventHandler _myDoWork;
34 private RunWorkerCompletedEventHandler _myWorkerCompleted;
35 private ProgressChangedEventHandler _myWorkerProgressChanged;
36
40 [Description("Event handler to be run on a different thread when the operation begins."), Category("Asynchronous")]
41 public event DoWorkEventHandler DoWork
42 {
43 add
44 {
45 _myDoWork += value;
46 }
47 remove
48 {
49 _myDoWork -= value;
50 }
51 }
52
56 [Description("Raised when the worker has completed (either through success, failure or cancellation)."), Category("Asynchronous")]
57 public event RunWorkerCompletedEventHandler RunWorkerCompleted
58 {
59 add
60 {
61 _myWorkerCompleted += value;
62 }
63 remove
64 {
65 _myWorkerCompleted -= value;
66 }
67 }
68
69
73 [Description("Occurs when ReportProgress is called.).")]
74 public event ProgressChangedEventHandler ProgressChanged
75 {
76 add
77 {
78 _myWorkerProgressChanged += value;
79 }
80 remove
81 {
82 _myWorkerProgressChanged -= value;
83 }
84 }
85
92 public bool IsBusy
93 {
94 get
95 {
96 return _myWorker.IsBusy;
97 }
98 }
99
107 {
108 get
109 {
110 return _myWorker.WorkerReportsProgress;
111 }
112 set
113 {
114 _myWorker.WorkerReportsProgress = value;
115 }
116 }
117
125 {
126 get
127 {
128 return _myWorker.WorkerSupportsCancellation;
129 }
130 set
131 {
132 _myWorker.WorkerSupportsCancellation = value;
133 }
134 }
135
145 public void CancelAsync()
146 {
147 _myWorker.CancelAsync();
148 }
149
157 {
158 get
159 {
160 return _myWorker.CancellationPending;
161 }
162 }
163
164#region Worker Async Request
165
166 private class WorkerAsyncRequest : ContextParams
167 {
168 public object Argument { get; private set; }
169
170 public WorkerAsyncRequest(object argument)
171 {
172 this.Argument = argument;
173 }
174 }
175
176 private class WorkerAsyncResult
177 {
178 public object Result { get; private set; }
179 public Csla.Core.ContextDictionary GlobalContext { get; private set; }
180 public Exception Error { get; private set; }
181 public bool Cancelled { get; private set; }
182
183 public WorkerAsyncResult(object result, Csla.Core.ContextDictionary globalContext, Exception error)
184 {
185 this.Result = result;
186 this.GlobalContext = globalContext;
187 this.Error = error;
188 }
189 }
190
191#endregion
192
193#region GlobalContext
194
195
200 public Csla.Core.ContextDictionary GlobalContext { get; private set; }
201
202#endregion
203
204#region RunWorkerAsync
205
215 public void RunWorkerAsync()
216 {
217 RunWorkerAsync(null);
218 }
219
227 public void RunWorkerAsync(object argument)
228 {
229 _myWorker.RunWorkerAsync(new WorkerAsyncRequest(argument));
230 }
231
232
233#endregion
234
235#region Private methods
236
244 void InternalDoWork(object sender, DoWorkEventArgs e)
245 {
246 var request = (WorkerAsyncRequest)e.Argument;
247
248 // set the background worker thread context
249 request.SetThreadContext();
250
251 try
252 {
253 var doWorkEventArgs = new DoWorkEventArgs(request.Argument);
254 if (_myDoWork != null)
255 {
256 _myDoWork.Invoke(this, doWorkEventArgs);
257 }
258#pragma warning disable CS0618 // Type or member is obsolete
259 e.Result = new WorkerAsyncResult(doWorkEventArgs.Result, Csla.ApplicationContext.GlobalContext, null);
260#pragma warning restore CS0618 // Type or member is obsolete
261 e.Cancel = doWorkEventArgs.Cancel;
262 }
263 // must implement exception handling and return exception in WorkerAsyncResult
264 catch (Exception ex)
265 {
266#pragma warning disable CS0618 // Type or member is obsolete
267 e.Result = new WorkerAsyncResult(null, Csla.ApplicationContext.GlobalContext, ex);
268#pragma warning restore CS0618 // Type or member is obsolete
269 }
270 }
271
279 private void InternalRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
280 {
281
282
283 Exception error = null;
284 object result = null;
285
286 if (!e.Cancelled)
287 {
288 var workerResult = (WorkerAsyncResult)e.Result;
289 // always set GlobalContext returned in the BW
290 // so it can be addressed in RunWorkerCompleted.
291 GlobalContext = workerResult.GlobalContext;
292
293 // must check for error as accessing e.Result will throw exception
294 // if e.Error is not null.
295 error = workerResult.Error;
296 if (workerResult.Error == null)
297 {
298 result = workerResult.Result;
299 }
300 }
301
302
303 if (_myWorkerCompleted != null)
304 {
305 _myWorkerCompleted.Invoke(this, new RunWorkerCompletedEventArgs(result, error, e.Cancelled));
306 }
307 }
308
317 private void InternalProgressChanged(object sender, ProgressChangedEventArgs e)
318 {
319 if (_myWorkerProgressChanged != null)
320 {
321 _myWorkerProgressChanged.Invoke(this, new ProgressChangedEventArgs(e.ProgressPercentage, e.UserState));
322 }
323 }
324
329 public void ReportProgress(int percentProgress)
330 {
331 _myWorker.ReportProgress(percentProgress);
332 }
333
339 public void ReportProgress(int percentProgress, object userState)
340 {
341 _myWorker.ReportProgress(percentProgress, userState);
342 }
343
344#endregion
345 }
346}
Dictionary type that is serializable with the SerializationFormatterFactory.GetFormatter().
A BackgroundWorker that wraps a System.ComponentModel.BackgroundWorkertransfers ApplicationContext....
void ReportProgress(int percentProgress)
Calls report progress on the underlying background worker.
bool WorkerReportsProgress
Gets or sets a value indicating whether the T:System.ComponentModel.BackgroundWorker can report progr...
Csla.Core.ContextDictionary GlobalContext
Gets a reference to the global context returned from the background thread and/or server.
DoWorkEventHandler DoWork
Occurs when M:System.ComponentModel.BackgroundWorker.RunWorkerAsync is called.
RunWorkerCompletedEventHandler RunWorkerCompleted
Occurs when the background operation has completed, has been canceled, or has raised an exception.
ProgressChangedEventHandler ProgressChanged
Occurs when M:System.ComponentModel.BackgroundWorker.ReportProgress is called.
bool IsBusy
Gets a value indicating whether the T:System.ComponentModel.BackgroundWorker is running an asynchrono...
void CancelAsync()
Request cancelation of async operation.
bool CancellationPending
Gets a value indicating whether the application has requested cancellation of a background operation.
bool WorkerSupportsCancellation
Gets or sets a value indicating whether the T:System.ComponentModel.BackgroundWorker supports asynchr...
void ReportProgress(int percentProgress, object userState)
Calls report progress on the background worker.
void RunWorkerAsync()
Starts execution of a background operation.
void RunWorkerAsync(object argument)
Starts execution of a background operation.
BackgroundWorker()
Initializes a new instance of the BackgroundWorker class.
@ Error
Represents a serious business rule violation that should cause an object to be considered invalid.