5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2006 Novell, Inc.
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections.Generic;
32 using System.Threading;
34 namespace System.ComponentModel
36 public class BackgroundWorker : Component
38 public BackgroundWorker ()
43 bool cancel_pending, report_progress = false, support_cancel = false;
45 Dictionary<object,AsyncOperation> operations =
46 new Dictionary<object,AsyncOperation> ();
48 public event DoWorkEventHandler DoWork;
49 public event ProgressChangedEventHandler ProgressChanged;
50 public event RunWorkerCompletedEventHandler RunWorkerCompleted;
53 public bool CancellationPending {
54 get { return cancel_pending; }
59 get { return async != null; }
62 [DefaultValue (false)]
63 public bool WorkerReportsProgress {
64 get { return report_progress; }
65 set { report_progress = value; }
68 [DefaultValue (false)]
69 public bool WorkerSupportsCancellation {
70 get { return support_cancel; }
71 set { support_cancel = value; }
74 [MonoTODO ("What should happen when IsBusy != true?")]
75 public void CancelAsync ()
78 throw new InvalidOperationException ("This background worker does not support cancellation.");
80 // FIXME: verify the expected behavior
84 cancel_pending = true;
86 async.PostOperationCompleted (delegate (object darg) {
87 OnRunWorkerCompleted (
88 new RunWorkerCompletedEventArgs (
91 cancel_pending = false;
96 public void ReportProgress (int percentProgress)
98 ReportProgress (percentProgress, null);
101 [MonoTODO ("What should happen when IsBusy != true?")]
102 public void ReportProgress (int percentProgress, object userState)
104 if (!WorkerReportsProgress)
105 throw new InvalidOperationException ("This background worker does not report progress.");
107 // FIXME: verify the expected behavior
111 async.Post (delegate (object o) {
112 ProgressChangedEventArgs e = o as ProgressChangedEventArgs;
113 OnProgressChanged (e);
115 new ProgressChangedEventArgs (percentProgress, userState));
118 public void RunWorkerAsync ()
120 RunWorkerAsync (null);
123 delegate void ProcessWorkerEventHandler (object argument, AsyncOperation async, SendOrPostCallback callback);
125 void ProcessWorker (object argument, AsyncOperation async, SendOrPostCallback callback)
128 Exception error = null;
129 DoWorkEventArgs e = new DoWorkEventArgs (argument);
132 } catch (Exception ex) {
135 callback (new object [] {
136 new RunWorkerCompletedEventArgs (
137 e.Result, error, e.Cancel),
141 void CompleteWorker (object state)
143 object [] args = (object []) state;
144 RunWorkerCompletedEventArgs e =
145 args [0] as RunWorkerCompletedEventArgs;
146 AsyncOperation async = args [1] as AsyncOperation;
148 SendOrPostCallback callback = delegate (object darg) {
149 OnRunWorkerCompleted (darg as RunWorkerCompletedEventArgs);
152 async.PostOperationCompleted (callback, e);
157 public void RunWorkerAsync (object argument)
160 throw new InvalidOperationException ("The background worker is busy.");
162 async = AsyncOperationManager.CreateOperation (this);
164 ProcessWorkerEventHandler handler =
165 new ProcessWorkerEventHandler (ProcessWorker);
166 handler.BeginInvoke (argument, async, CompleteWorker, null, null);
169 protected virtual void OnDoWork (DoWorkEventArgs e)
175 protected virtual void OnProgressChanged (ProgressChangedEventArgs e)
177 if (ProgressChanged != null)
178 ProgressChanged (this, e);
181 protected virtual void OnRunWorkerCompleted (RunWorkerCompletedEventArgs e)
183 if (RunWorkerCompleted != null)
184 RunWorkerCompleted (this, e);