Как я могу обновить индикатор выполнения пользовательского интерфейса или фоновый работник из кода в отдельном классе? - PullRequest
2 голосов
/ 15 ноября 2010

Несколько плохо знаком с C #, но у меня есть серьезная проблема с тем, чтобы заставить эти вещи работать, потому что если мой фоновый работник выполняет длинный процесс с использованием метода из другого класса, то у этого класса нет доступа к фоновому работнику, чтобы обновить прогресс.

Например:

private void bgWorker_DoWork(object sender DoWorkEventArgs e)
{
    bgArgs args = e.Argument as bgArgs;
    MyClass objMyClass = new MyClass();

    MyClass.MyMethod(strValue, args.Option);

    //Do something based on return value of long process.
}

Если я пытаюсь обновить bgWorker из класса «MyClass», он не может «видеть» bgWorker, он не существует в контексте класса, он находится в классе пользовательского интерфейса, потому что в Visual Studio его можно перетащить из панели инструментов.

Единственный способ заставить его работать - это передать всю форму пользовательского интерфейса классу, что создает другие проблемы при попытке доступа к этому классу из любой точки, кроме основной формы. Оттуда я просто обновляю индикатор выполнения вручную через ProgressBar1.PerformStep (), поскольку он проходит через циклы.

Кроме того, я уже изменил модификатор на индикаторе выполнения на внутренний, так что класс не видит индикатор выполнения.

Возможно, я смогу передать bgworker самому классу через метод, но это не совсем верно.

Ответы [ 2 ]

1 голос
/ 15 ноября 2010

Предполагая, что я правильно понимаю ваш вопрос, вам, вероятно, нужно создать метод, который может получить доступ к UB progressBar, несмотря на исходный поток.Ниже приведено только то, что избавит вас от взрыва приложения при попытке установить значение.

private delegate void UpdateProgressBarCallback(int barValue);
private void UpdateProgressBarHandler(int barValue)
{
    if (this.progressBar1.InvokeRequired)
        this.BeginInvoke(new UpdateProgressBarCallback(this.UpdateProgressBarHandler), new object[]{ barValue });
    else
    {
        // change your bar
        this.progressBar1.Value = barValue;
    }
}

[см. http://msdn.microsoft.com/en-us/library/ms171728%28VS.80%29.aspx]

Затем вы просто вызываете UpdateProgressBar(значение);(аналогично, если вы хотите, чтобы это пошагово, вы можете настроить аргументы / способ работы метода)

Далее вы можете сделать это несколькими способами: вы можете сделать свой фоновый рабочий (так как он уже находится в другом классе)управляемый событиями, а затем прикрепите изменения прогресса и обновите пользовательский интерфейс;или вы можете передать делегата работникам потоков в качестве справки, чтобы он знал, где настроить пользовательский интерфейс.

Прокомментируйте и оставьте мне направление, и я посмотрю, смогу ли я вам помочь (и подтвердитепонять вопрос).

1 голос
/ 15 ноября 2010

Я думаю, что ваша архитектура нуждается в пересмотре здесь.Фоновый рабочий предназначен для выполнения операций в фоновом режиме, например, вне поля зрения.Пока он работает, вы можете принять от него обратную связь, наблюдая событие BackgroundWorker.ProgressChanged, которое поможет вам увеличить индикатор выполнения с помощью PerformStep ().Однако вы не должны пытаться изменить BackgroundWorker во время его работы.Это приводит вас к проблемам Threading , которые я не уверен, что вы действительно хотите :) Видите ли, BackgroundWorker использует другой поток для выполнения своих операций при запуске, поэтому изменение его во время работы означает, что вы должныполучить доступ к потоку, над которым он выполняет свою работу.Это становится ужасноЛучше всего просто дать ему метод для выполнения, дать ему работать, проверить его ProgressChanged и дождаться его завершения.

...