Note that there are some explanatory texts on larger screens.

plurals
  1. POEvent Handlers in Constructors - Is it Possible or Even Wise?
    primarykey
    data
    text
    <p>I have an object that can take anywhere from a split second to a couple of minutes to initialize. The reason being is that the constructor retrieves data from a webservice that could be a few kilobytes to several megabytes, and depending on the user's connection speed performance may vary greatly. For that reason I am wanting to put events in that will handle progress notification. </p> <blockquote> <p>Here is my question: Can I put event handlers in the constructor or should this type of action be done with a Load method?</p> </blockquote> <p>For example:</p> <pre><code>public class MyObject { public event EventHandler&lt;UpdateLoadProgressEventArgs&gt; UpdateLoadProgress; public MyObject(int id) { Background worker bgWorker = new BackgroundWorker(); bgWorker.DoWork += delegate(object s, DoWorkEventArgs args) { //load data and update progress incrementally UpdateLoadProgress(this, new UpadteLoadProgressEventArgs(progressValue)); Result = someValue; } bgWorker.RunWorkAsync(); } public int Result { get; set; } } </code></pre> <p>However when I try to tie the event handlers to the constructor they are always null when being called:</p> <pre><code>MyObject o = new MyObject(1); o.UpdateLoadProgress += new EventHandler&lt;EventArgs&gt;(o_UpdateLoadProgress); </code></pre> <p>I assume this happens because I wire up the events after the constructor. The only alternative I see is creating a Load method that does the work of the constructor. The downside is that anyone that uses this class must know to call Load before trying to access Result (or any other property). </p> <p><strong>EDIT:</strong> Here is the final solution:</p> <p><strong>MyObjectBuilder Class</strong></p> <pre><code>public class MyObjectBuilder { public event ProgressChangedEventHandler ProgressChanged; public MyObject CreateMyObject() { MyObject o = new MyObject(); o.Load(ProgressChanged); return o; } } </code></pre> <p><strong>MyObject Class</strong></p> <pre><code>public class MyObject { public int Result { get; set;} public void Load(ProgressChangedEventHandler handler) { BackgroundWorker bgWorker = new BackgroundWorker(); bgWorker.WorkerReportsProgress = true; bgWorker.ProgressChanged += handler; bgWorker.DoWork += delegate(object s, DoWorkEventArgs args) { for (int i = 0; i &lt; 100; i++) { Thread.Sleep(10); Result = i; bgWorker.ReportProgress(i); } }; bgWorker.RunWorkerAsync(); } } </code></pre> <p><strong>Program Class</strong></p> <pre><code>class Program { static void Main(string[] args) { MyObjectBuilder builder = new MyObjectBuilder(); builder.ProgressChanged += new ProgressChangedEventHandler(builder_ProgressChanged); MyObject o = builder.CreateMyObject(); Console.ReadLine(); } static void builder_ProgressChanged(object sender, ProgressChangedEventArgs e) { Console.WriteLine(e.ProgressPercentage); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload