Фоновые рабочие

Я сделал метод, который перечисляет все папки ftp в пути.
Моя проблема в том, что мне нужно вернуть это как массив.
Но это фоновый рабочий процесс, и я могу вернуть его только в "RunWorkerCompleted",
с e.Result.
1) Как передать параметр методу?(фонового воркера)
2) Как вернуть массив папок к нормальному метод?
Вот так:

private void btnOpen_Click_1(object sender, EventArgs e)
        {
           string[]/List... a=  getDirectories(**path**)?
        }

person funerr    schedule 07.10.2011    source источник


Ответы (2)


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

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

Однако вы должны быть осторожны с этим подходом, чтобы не получить доступ к этому списку во время работы работника; так как это не потокобезопасно. В .Net 4 вы можете использовать ConcurrentBag, который является потокобезопасным. .

Если вы не хотите этого делать, то член Result аргументов события, переданных в событии RunWorkerCompleted, как вы говорите, используется для сообщения результатов - и именно туда вы должны вернуть свой список. Вы также можете использовать событие ProgressChanged (в MSDN) для потоковой передачи отдельных моментальных снимков результатов.

Я не думаю, что это необоснованно: асинхронные операции — это принципиально иная парадигма по сравнению с синхронными вызовами, вы просто не можете использовать ту же семантику вызова и возврата.

person Andras Zoltan    schedule 07.10.2011
comment
Да, я думал об этом. Но я хочу каждый раз возвращать массив определенному методу... не RunWorkerCompleted. - person funerr; 07.10.2011

Вы можете передавать свои аргументы, поскольку они являются объектами. BackgroundWorker принимает параметр object. Переменная object может содержать что угодно: массив, ссылки и переменные.

Пример:

object[] args = new object[] { fileName, ....... };
this.backgroundWorker1.RunWorkerAsync(args);

в методе:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            object o = e.Argument;
            object[] args = (object[])o;
            string fileName = (string)args[0];
            ....
            object[] result = ....
            e.Result = result;
        }

Когда работа завершена:

void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            object o = e.Result;
            object[] result = (object[])o;
            ...
        }
person Community    schedule 07.10.2011
comment
Проблема в том, что я создаю метод, который загружает все файлы в каталог, и я использую рекурсию, тогда мне нужно вернуть массив этому методу, а не RunWorkerComplete. - person funerr; 07.10.2011
comment
@askingDude Можете ли вы показать свой код? я ничего не понял - person ; 07.10.2011
comment
Спасибо, но сейчас я пытаюсь использовать потоки, может быть, они помогут. если нет, я опубликую свой код. - person funerr; 07.10.2011