У меня есть объект, который может взять где угодно с доли секунды до нескольких минут для инициализации. Так как причина, то, что конструктор получает данные из веб-сервиса, который мог быть несколькими килобайтами к нескольким мегабайтам, и в зависимости от скорости соединения пользователя производительность может варьироваться значительно. По этой причине я желаю поместить события в это, обработает уведомление о прогрессе.
Вот мой вопрос: я могу поместить обработчики событий в конструктора, или этот тип действия должен быть сделан с методом Загрузки?
Например:
public class MyObject
{
public event EventHandler<UpdateLoadProgressEventArgs> 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;
}
}
Однако, когда я пытаюсь связать обработчики событий с конструктором, они являются всегда пустыми, будучи названным:
MyObject o = new MyObject(1);
o.UpdateLoadProgress += new EventHandler<EventArgs>(o_UpdateLoadProgress);
Я предполагаю, что это происходит, потому что я обеспечиваю электричеством события после конструктора. Единственная альтернатива, которую я вижу, создает метод Загрузки, который делает работу конструктора. Оборотная сторона - то, что любой, который использует этот класс, должен знать к нагрузке по вызовам прежде, чем попытаться получить доступ к Результату (или любое другое свойство).
Править: Вот конечное решение:
Класс MyObjectBuilder
public class MyObjectBuilder
{
public event ProgressChangedEventHandler ProgressChanged;
public MyObject CreateMyObject()
{
MyObject o = new MyObject();
o.Load(ProgressChanged);
return o;
}
}
Класс MyObject
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 < 100; i++)
{
Thread.Sleep(10);
Result = i;
bgWorker.ReportProgress(i);
}
};
bgWorker.RunWorkerAsync();
}
}
Класс программы
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);
}
}