Передать BackgroundWorker в класс, вызываемый doWork? - PullRequest
0 голосов
/ 03 апреля 2012

Возможно ли это?

Я хочу, чтобы мой метод doWork создал экземпляр другого класса и затем вызвал его метод запуска.Затем я хотел бы сообщить о прогрессе от этого класса обратно обработчику ProgressChanged в родительском классе.Я пытался передать ссылку на BackgroundWorker, но я получаю сообщение об ошибке.

private void ComplianceWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        ComplianceControlCenter CCC = 
         new ComplianceControlCenter(taskList.CheckedItems.OfType<string>().ToList(),
                                     file_box.Text, &ComplianceWorker);
        CCC.start();
    }

РЕДАКТИРОВАТЬ:

Есть только 1 фоновый работник.Я хотел бы передать его по ссылке на конструктор ComplianceControlCenter, чтобы я мог отправлять ему обновления прогресса из этого класса.Смысл в том, что класс выполняет довольно сложную работу, и мне нужно разделение.Итак, еще раз, я хотел бы передать фонового работника из метода doWork в объект CCC, чтобы я мог вызвать ComplianceWorker.ReportProgress();

Ошибка 1 Не удается получить адрес, получить размер или объявитьуказатель на управляемый тип ('System.ComponentModel.BackgroundWorker')

Ответы [ 6 ]

1 голос
/ 03 апреля 2012

В C # ссылки передаются следующим образом:

ComplianceControlCenter CCC = new ComplianceControlCenter(..., ComplianceWorker);

не так

ComplianceControlCenter CCC = new ComplianceControlCenter(..., &ComplianceWorker);

В качестве дополнительного примечания принято, чтобы переменные и поля начинались со строчной буквы, поэтому я бы переименовал ComplianceWorker в complianceWorker. Обратите внимание, что это также улучшает подсветку синтаксиса в StackOverflow:; -)

ComplianceControlCenter ccc = new ComplianceControlCenter(..., complianceWorker);
0 голосов
/ 04 апреля 2012

Решил это, сделав это ..

ComplianceControlCenter CCC = new ComplianceControlCenter(taskList.CheckedItems.OfType<string>().ToList(), file_box.Text,ref complianceWorker);

С этим в качестве конструктора.

public ComplianceControlCenter(List<string> task_list, String exe_location, ref BackgroundWorker complianceWorker)
0 голосов
/ 03 апреля 2012

Если вам нужно само значение BackgroundWorker в событии DoWork, просто увеличьте значение sender.Может быть, что-то вроде этого:

private void ComplianceWorker_DoWork(object sender, DoWorkEventArgs e)
{
    var worker = sender as BackgroundWorker;
    if(worker == null)
    {
        //ToDo: What should happen if MS changes the behavior??
    }

    ComplianceControlCenter CCC = new ComplianceControlCenter(taskList.CheckedItems.OfType<string>().ToList(), file_box.Text, worker);
    CCC.start();
}
0 голосов
/ 03 апреля 2012

Почему бы просто не передать ссылку на ваш BackgroundWorker в качестве параметра вашему методу "работа"?

EDIT:

Фактически вы должны сделать это, если хотите сообщить о прогрессе или установить флажок CancellationPending, если вы также можете отменить операцию вручную.

0 голосов
/ 03 апреля 2012

Вы могли бы сделать это, хотя я не понимаю, для чего это будет полезно в простых случаях. Поскольку вы уже в бизнес-методе BackgroundWorker, нет смысла использовать еще больше потоков, создав еще один BackgroundWorker, и вы можете выполнить ту же самую работу на линии.

Если вы все еще хотите иметь вторую BackgroundWorker, вы можете передавать события с измененным прогрессом от второго рабочего к первому, прикрепив обработчик к событию ProgressChanged второго рабочего. Затем этот обработчик вызовет событие ProgressChanged для первого работника, распространяя новости.

Например:

private void ComplianceWorker_DoWork(object sender, DoWorkEventArgs e)
{
    var CCC = new ComplianceControlCenter(/* ... */);

    // Assume that CCC exposes a BackgroundWorker, but read below
    var worker = CCC.Worker; // "second" worker
    worker.ProgressChanged += this.PropagateProgressChanged;

    CCC.start();
}

private void PropagateProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var worker = this.worker; // "first" worker
    worker.ReportProgress(e.ProgressPercentage, e.UserState);
}

Этот код присоединяет обработчик событий ко «второму» работнику с

var worker = CCC.Worker; // "second" worker
worker.ProgressChanged += this.PropagateProgressChanged;

, который предполагает, что ComplianceControlCenter выставляет свой собственный BackgroundWorker напрямую. Поскольку это может быть не так, вы можете изменить отношение, передав вместо этого ссылку на this.PropagateProgressChanged в конструктор и разрешив ему присоединить обработчик событий для вас.

0 голосов
/ 03 апреля 2012

если оба фоновых рабочих одинаковы, вы попадете в бесконечный цикл.возможно, создать двух разных фоновых рабочих.если вам требуется нечто подобное между ними, создайте базовый класс / интерфейс.

...